hachyderm.io is one of the many independent Mastodon servers you can use to participate in the fediverse.
Hachyderm is a safe space, LGBTQIA+ and BLM, primarily comprised of tech industry professionals world wide. Note that many non-user account types have restrictions - please see our About page.

Administered by:

Server stats:

8.9K
active users

Brian Kung

I'm doing a code challenge in Crystal. As someone who with a Ruby background who went on to learn Rust, you might think that it's a natural fit. However, I'm finding it to fall in the uncanny valley between the two - not as flexible as Ruby and not as expressive a type system as Rust, and the two play off of each other when I'm trying to do type gymnastics to get this very Ruby-like language to behave like Ruby.

I want a RecursiveHash with values of the type RecursiveHash. Basically this in Ruby:

h = {}
h[:a] = {}

So if you start writing it in Crystal, you get:

hash = Hash(Char, Hash(Char, ???)).new

And I won't know how many levels deep the Hash is until runtime.

@EndlessMason IIUC that's basically what I want! Is that a Python thing?

@briankung Yes. It's a python thing...

In perl we call it a hash-ref, they just do be like that

@briankung it's not as ergonomic as ruby, but in crystal you can declare recursive type aliases, which help with that specific problem:

alias RecursiveHash::Types = Hash(Char, RecursiveHash::Types) | String

h = Hash(Char, RecursiveHash::Types).new
h['a'] = Hash(Char, RecursiveHash::Types).new
h['b'] = "B"

a = h['a'].as(Hash(Char, RecursiveHash::Types))
a['a'] = Hash(Char, RecursiveHash::Types).new
a['b'] = "BB"

the cost is some syntax to cast the union type to the specific recursive type, but you avoid static nested types.

@toddsundsted Ah, gotcha, I see where I went wrong. I was trying something similar but tried to use h = RecursiveHash(...). Thank you so much!