I don't just drink coffee or booze, watch movies and Internet drama, and look cool. I code sometimes, too! Who knew?!
Carrying on with my experiment in Julia, packaging has another step needed to make references. For instance, Ansi uses Geometry, so:
Geometry/Project.toml:
authors = ["Mark Damon Hughes "]
name = "Geometry"
uuid = "e3172796-a620-11e8-2cbf-612649bb77f8"
version = "0.1.0"
[deps]
Ansi/Project.toml:
authors = ["Mark Damon Hughes "]
name = "Ansi"
uuid = "72992c94-a620-11e8-3d05-55611ea0dbd0"
version = "0.1.0"
[deps]
Geometry = "e3172796-a620-11e8-2cbf-612649bb77f8"
Ansi/Manifest.toml:
[[Geometry]]
repo-rev = "master"
repo-url = "/Users/mdh/Code/CodeJulia/Geometry"
uuid = "e3172796-a620-11e8-2cbf-612649bb77f8"
version = "0.1.0"
All the boldface code is what I wrote/copy-pasted, the rest is generated by juliaMakePackage.zsh
. I may go ahead and make a tool to link projects, because it's so error-prone. In fact, I cheated, and made a single Manifest.toml which I copy to all projects so far, and can replace whenever something updates.
Anyway, this gets me to a nice state where I can write using Ansi
in my project and it'll just find it. IIUC, if I move all the libraries to a public repository, I can just change the repo-url and the packages are downloaded into ~/.julia cache somewhere.
I still haven't followed up on making a binary application; the more I look into that, the jankier it seems, more like something to defer until there's an official solution. Putting a real UI on it is also something to work on, but that's much more doable.
Coding
I've written a lot more code, over 1000 LOC, not just screwing around with packages. Mostly this is enjoyable, it's a nice systems programming language. The ugly parts haven't yet driven me insane, they're just things to work around or ignore. Far less frustrating than almost any other new language; Rusty Nail In Your Head and Go Fuck Yourself Its Google aren't my favorites.
Strong typing really is a pain in the ass. Declare a variable or struct field foo
, and it takes anything. Type it with foo::AbstractString
, and you soon learn nothing
is not a string; foo::Union{AbstractString,Nothing}
is necessary to be nullable. Ick.
Enumerations
Enumerated types @enum
are disappointing. They're a little smarter than C enums, but not as useful as Java enums. They just represent a value; but you have to cast them to Int every time you use them for their value, so too painful to use them as array indices. Or as characters, a thing I like a lot for debugging. And they're not easy to reflect on:
julia> @enum Terrains begin
Ter_Floor = Int('.')
Ter_Wall = Int('#')
end
julia> Ter_Wall
Ter_Wall::Terrains = 35
julia> Int(Ter_Wall)
35
julia> Char(Int(Ter_Wall))
'#': ASCII/Unicode U+0023 (category Po: Punctuation, other)
julia> String(Char(Int(Ter_Wall)))
ERROR: MethodError: no method matching String(::Char)
julia> string(Char(Int(Ter_Wall)))
"#"
julia> # FFS
julia> string(Ter_Floor)
"Ter_Floor"
julia> # Surprisingly easy!
julia> instances(Terrains)
(Ter_Floor::Terrains = 46, Ter_Wall::Terrains = 35)
julia> # Shit, this is a named tuple, not a dictionary!
julia> useful_instances = Dict()
Dict{Any,Any} with 0 entries
julia> for v in values(instances(Terrains))
useful_instances[ string(v) ] = v
useful_instances[ string(Char(Int(v))) ] = v
end
julia> useful_instances
Dict{Any,Any} with 4 entries:
"Ter_Floor" => Ter_Floor
"Ter_Wall" => Ter_Wall
"#" => Ter_Wall
"." => Ter_Floor
julia> # JFHC
That was an annoying adventure to get a simple reverse lookup.