Learn Elixir — chapter by chapter explanation of Programming Elixir 1.6 (by Dave Thomas)

Chapter 1 and 2 — OOP, Functional Programming, and Pattern Matching Chapter 3 — Immutability Chapter 4 — Basic Elixir Types Chapter 5 — Anonymous Functions (this post) Chapter 6 — Modules and Named Functions (coming soon) Chapter 7 — Lists and Recursion (coming soon) Chapter 8 and 9 — Maps, Structs, and Keyword Lists in Detail (coming soon) Chapter 10 — Processing Collections (coming soon) Chapter 11 — Strings and Binaries (coming soon) Chapter 12 — Control Flow (coming soon)

Welcome back to my 4th post in this series where I share key learnings from each chapter of Programming Elixir 1.6. If you haven’t read my previous posts yet, feel free to check those out first before continuing. In this post, I’ll be discussing anonymous functions in Elixir.

Chapter 5

Basic syntax of anonymous functions

Anonymous functions begin with the fn keyword and end with the end keyword. In between the fn and end keywords, you declare your parameter list followed by your function body. So far, this is very similar to other languages like JavaScript and Ruby.

Anonymous functions in different languages

2. How to invoke anonymous functions

Even though we haven’t touched on named functions yet, the book makes a note to differentiate between anonymous and named functions. In particular, one of the differences between the 2 types of functions is how they are invoked.

Comparing how anonymous and named functions in Elixir are invoked

3. Functions are not variadic

Because of my JavaScript background, something I immediately noticed when working with anonymous functions in Elixir is that they can only take on as many arguments as defined in their parameter list. Thinking about the same sum function in example 1 above, it’s possible to define it in JavaScript so that it can take on as many arguments as you want.

Functions in JavaScript can be passed as many arguments as you want

But in Elixir, if you defined your anonymous function with just 2 parameters, then it’ll only take 2 arguments when you call it. Although this seems like a limitation, I think we’ll see this make more sense when we look at how pattern matching works for functions in Elixir.

4. Pattern matching in functions

If you remember from Ch. 2, we discussed pattern matching using the match operator (i.e. the = sign). At that time, we might have only thought that pattern matching works only with the match operator. The next point might seem subtle but it really highlights how pervasive pattern matching is in Elixir — when we invoke an Elixir function by passing arguments to it, we’re not actually assigning values to the parameters. Instead, we’re finding the function clause that successfully matches the arguments to the parameter list in the function. If this isn’t clear, hold your thought until the next section and it’s example :)

5. Functions in Elixir can have multiple function clauses

In Elixir, a single function definition lets you define multiple function clauses, depending on the type and contents of the arguments passed. However, the different function clauses for a function definition MUST have the same arity — in other words, it must have the same number of parameters defined. Let’s take a look at an example.

Pattern Matching and Multiple Function Clauses in Elixir

6. Classic FizzBuzz example in Elixir and JavaScript

Just to really hit the nail on the head on how cool pattern matching is in Elixir, I’ll share an exercise example from the chapter which is to implement the classic FizzBuzz puzzle. I’ll do this in both Elixir and JavaScript to compare and contrast them.

FizzBuzz all the things!

6. Anonymous functions are closures

So far, I’ve only mentioned one difference between anonymous and named functions in Elixir — which is how they are invoked differently. Here’s another key difference — anonymous functions in Elixir are closures. In other words, anonymous functions in Elixir automatically carry with them the bindings of variables in the scope in which they are defined. They remember the original environment they were defined in, as well as the other bindings that exist in that environment. For those of you who also come from a JavaScript background, this should be familiar to you as well since JavaScript functions are all closures as well.

7. Shorthand notation for anonymous functions

When I read about the shorthand notation, I thought it was pretty cool because it mirrored arrow functions in JavaScript. Here’s how the shorthand notation works in Elixir:

Normal and shorthand notation for anonymous functions in Elixir

In my next blog post, we’ll go over Chapter 6 in Programming Elixir 1.6 which focuses on modules and named functions in Elixir.