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 end
keywords.
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.
Leave a Reply