What's the reasoning behind => for hashes and -> for procedure types?

Why be different when most programmers already know for hash (or dictionary), you use colons:

someHash = { “one”: 1, “two”: 2 }

With the Crystal way, you have to type two characters vs one. Seems pointless to change it from other languages unless there’s a reason I don’t know about.

Also, for procedures, why not just use:

proc = (x : Int32, y : Int32) => { x + y }
or
proc = () => { puts “hello, world” }

Why bother with the leading: ->?

Using a : denotes a NamedTuple. So that syntax was already taken. Similarly I’d imagine because => is used for Hash so needed something unique?

EDIT: You can also do Proc(Nil).new { puts "foo" }

Seems pointless to change it from other languages unless there’s a reason I don’t know about.

One thing to keep in mind is that a lot of Crystal was inspired by Ruby, and for us Ruby developers => is what was used for hashes. Though, Ruby does allow for using : now, it didn’t always. Plus, PHP also uses the rocket syntax in the assoc arrays ["key" => "value"]. And perl uses this syntax %data = ('John Paul' => 45);. I’m sure there’s some other languages out there that use this syntax as well, but I’d say since Ruby took inspiration from Perl, and Crystal took inspiration from Ruby, we get => with our hashes. The same goes for the Proc literal syntax.

Now, granted, Crystal isn’t trying to mimic Ruby 1 to 1, but you have to also keep in mind that Crystal has been in development for over 5 years now (7 maybe?), so this could have been an easy thing to change years ago, but for now since it’s getting closer to 1.0, I see it sticking around for the long run. (I personally love the syntax :laughing:)

1 Like

Depends on what other languages you compare with. Crystal’s hash syntax is 100% copied from Ruby. So for everyone coming from Ruby this feels completely natural. And as @jwoertink already mentioned, this dictionary syntax is quite common in other languages.

I don’t understand your argument about proc literals, though. In your examples, you place => between arguments and block. Crystal’s syntax just places -> in front of arguments. Why it’s -> and not => should be obvious because => is already used for dictionaries. I don’t think it’s much of a difference either way, though. Both symbols are pretty similar.
Regarding the placement, it surely makes sense to place it between arguments and block to represent a transformation operator between input on the left and output on the right. It would be a reasonable choice. That infix notation is also used for lambdas in other languages, like C++, Java and some functional languages. It’s however not always the only indicator, a keyword like fn often goes before the arguments.
Infix notation is common in the Lisp family, for example with a keyword like lambda followed by arguments and block.
Crystal’s syntax isn’t so much different from these examples. And again, the proc literal syntax is 100% copied from Ruby’s lambda literal.

I’m not exactly sure about the reasons to put it in front. But one benefit is that a prefix is much easier to parse and less ambiguous. And if you already have prefix, there’s no need for an additional infix.

2 Likes