Hello, Elixir!

A while ago, I talked about trying Elixir and finished with this example of Hello World

#!/usr/bin/env elixir

greet = fn s -> IO.puts "Hello, #{s}!" end

if length(System.argv) == 0 do
  greet.("World")
else 
  Enum.each(System.argv, greet)
end

This looks pretty much the same as it would in an imperative language. First, we define a greet function that prints “Hello, string!” for whatever string we give it. If we’re given no arguments, we call this with “World”. Otherwise, we call it for each of the arguments (okay, that part is already looking a tiny bit functional, since a for loop is missing).

But we don’t often use if-then-else in Elixir. I ended that post saying I would look for a more elixiry way to do it. I did so, but I didn’t post about it.

My second pass at hello world in Elixir looked like this

#!/usr/bin/env elixir

greet = fn s -> IO.puts "Hello, #{s}!" end

hello = fn
  [] -> greet.("World")
  list -> Enum.each(list, greet)
end

hello.(System.argv)

This is the same greet function, but rather than an if-then-else, we define a new function, hello, that has one behavior when handed an empty list and a different behavior when handed a non-empty list. Then we simply call this function with the argument list of the program.

For a third pass, I threw in Elixir’s amazing pipe operator.

#!/usr/bin/env elixir

greet = fn s -> IO.puts "Hello, #{s}!" end

hello = fn
  [] -> greet.("World")
  list -> list |> Enum.each(greet)
end

hello.(System.argv)

This doesn’t really show it off much, but the pipe operator seems to be an important part of Elixir’s readability in real code.

Finally, I learned that we usually name standalone scripts like this with a .exs rather than .ex in Elixir, so the new hello.exs works the same as before

$ ./hello.exs
Hello, World!
$ ./hello.exs Hank Dean Brock
Hello, Hank!
Hello, Dean!
Hello, Brock!

Keen!

Advertisements
Hello, Elixir!

Equals: a sign or assign

I enjoyed reading “How I learned to stop worrying and love the code” and as a teacher of The Code I took it to heart.

Number 3 is huge, I think. Most people think they know what this means

hello = 4

so if we don’t tell them straight away that it means something else, they might be confused for some time. I guess we can blame Fortran for originally abusing the “equals sign” that way, but that doesn’t really excuse all the languages that have repeated the blunder since then.

I think part of the issue is verbal. When I learned Pascal, which has a distinct assignment operator,

hello := 4

I developed the habit of pronouncing it “hello gets four” and that continues to this day… even in languages that use an equals sign. I’ve noticed that lots of programmers pronounce

hello = 4

“hello equals four,” even though they also pronounce

hello == 4

“hello equals four.” Having a verbal distinction between “hello gets four” and “hello equals four” is useful, in my mind. In practice, though, it’s not that helpful since few people I end up in a code review or pair programming situation with do the same.

It’s also worth noting that

hello = 4

means something a little different in Python, than in most other languages. Namely, it’s binding a name rather than assigning a value. This means that in addition to tripping up beginning programmers, it also trips up experienced programmers who are new to Python.

It means another thing in Erlang and yet another in Elixir. Both of these are matching, rather than simply assigning, but in slightly different ways. Again, this trips up experienced programmers who are new to Erlang or Elixir. It doesn’t mean “equals,” so the beginning programmers are confused, but it doesn’t mean “simple assignment” either, so the experienced programmers are confused too. It doesn’t even mean “bind,” so the Python programmers are confused as well.

I have often wondered if teaching Elixir to beginning programmers might be easier than teaching it to experienced programmers. Teaching Elixir (or Erlang or Clojure or any functional language) to someone who already knows imperative programming seems to involve as much un-learning as learning. If someone didn’t have any baggage from imperative programming, we could just teach them functional programming straight away. Someday, I’d like to try this.

Equals: a sign or assign