Julia More Packaging & Code

Julia language logo

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.