I wrote my very first program in Elixir as a learning exercise.
The program is a simple implementation of the Fizz-Buzz Test.
I felt like sharing my first encounter with Elixir; perhaps it will be useful for fellow beginners.
My main goals for this project were to:
- Try out Visual Studio Code with ElixirLS.
- Learn how to create a new project using
mix
. - Get an understanding of the files which are scaffolded by
mix
. - Learn how to use
ExUnit
for testing functions and module documentation. - Get some exposure to the language itself, to get comfortable with the syntax.
I intentionally kept all of the commits in the repo instead of squashing them together, so that I could study them to learn from my mistakes. My meandering is exposed for the world to see
A couple of things that surprised me:
- It was extremely easy to create a new project and grok
ExUnit
, due to its explicit nature. - Visual Studio Code with LanguageLS was a really great experience.
- I discovered a surprising bug the very first time I ran my tests.
- Having tests really sped up my development cycle, as I didn’t need to drop into
iex
.
Some difficulties I stumbled upon:
- I had to spend some time to get the ordering of the case clauses correct.
- For a while, I struggled with matching
0
, until I discovered how easy it was ({0, 0, 0}
). - It doesn’t seem like Elixir has an
is_range()
guard, so I had to find a different solution.- I first tried to implement my own
is_range()
guard withdefguardp
, but gave up on that when I wasn’t able to pattern-match or call a local function within the guard definition.
- I first tried to implement my own
- I wasn’t sure whether to use
Enum.map()
or list comprehension.- Both approaches worked, but I opted for
Enum.map()
because it looked nicer.
- Both approaches worked, but I opted for
One other thing that’s bugging me is this code:
n when is_list(n) ->
Enum.map(n, fn n -> check_number(n) end)
n = %Range{} ->
Enum.map(n, fn n -> check_number(n) end)
Because there is duplication; only the case differs. I haven’t figured out (yet) how to either match both of those clauses at once. Maybe I will extract that line to a private helper function.
Other than that, it was pretty much straightforward and an enjoyable experience.
A few areas I want to look into next:
- Adding specifications to functions using
@spec
.- Figure out if I can add type specs for multiple input values.