I’ve been working through Dave Thomas’s fantastic book Programming Elixir 1.6 in hopes of using Phoenix LiveView, and it has been really interesting, coming from Ruby. A lot of syntax is familiar enough to be alluring, but unfamiliar enough to trip me up. For instance, even something as simple as an
if block was hard to write fluently:
if true do something else something_else end
Rubyists, did you catch it?
if statements in Elixir have a mandatory
do...end block. I got stuck for longer than I’d like to admit trying to compile my Elixir code only to have it complain about superfluous
As it turns out, this makes sense because
do...end blocks are syntactic sugar for appending a keyword list to a function, and
if is just a function in Elixir. But in Ruby,
do...end blocks in
if statements are not even valid (that I know of).
I encountered a similar syntactical hiccup when converting short form function definitions to long ones in Elixir. Short function definitions follow this syntax:
def somefunc(arg), do: IO.inspect(arg)
…while long function definitions look like this:
def somefunc(arg) do IO.inspect(arg) end
Again, the differences are slight, but incompatible – and again, they make sense when you realize what the
do...end syntactic sugar is for. The short form of function definition requires a comma after the function arguments, and the long form will throw a syntax error if you forget to delete the comma and simply move the function body into a
do...end block. This is, as before, because the
do...end block is simply sugar for
do: (function_body) keyword list. But in order for it to be parsed as a keyword list in the short function definition, it needs the comma.
Once again, it makes sense! But it’s a tripping hazard for Rubyists.
Ironically, I couldn’t remember if the
do: keyword list in the short function definition required the
end keyword – even when writing this post! Spoiler: it is a syntax error.
It’s also a bit of a paradigm shift to write in a fully functional language after writing object oriented, message-passing Ruby code for so long, but I’ll leave that for another post.