Everyone knows Javascript. Your grandma, father-in-law, old college roommate… even your cat knows Javascript!

Javascript is among the most popular and in demand (read: mainstream) programming languages. That makes it Totally Uncool™.

Elixir, on the other hand, is new and exciting. Like Javascript, it is a multi-paradigm, dynamically-typed language that runs in a virtual machine. Yet unlike Javascript, Elixir has (almost) nothing to do with building interfaces.

Instead, Elixir was designed to elegantly reintroduce retro 1980’s tech like Erlang and the Open Telecom Platform (OTP). What could be cooler than an open-source toolset created by Ericsson for distributed, fault-tolerant systems like telephones switches?

Why Elixir?

In reality, Erlang/OTP is a solid foundation to build any ecosystem. Telecom services don’t have the luxury of scheduled maintenance windows. Imagine a call dropping or a text message bouncing because of server updates? Imagine an improperly routed text message in the wrong inbox?

Behind the scenes it’s powerful features like green threads and supervision trees that enable OTP services to be massively scalable and highly available. These benefits aren’t limited to telephony either. Consider WhatsApp, who scaled to over 900M users with just 50 engineers thanks in large part to OTP.

So why not just learn Erlang? So what’s with all the fuss about Elixir? Why does Elixir leave some to ask: Anyone just feel happy writing Elixir code?

From Javascript to Elixir

What Elixir brings to the table is a complete different surface syntax, inspired by Ruby. What you might call a “non-scary” syntax, and a load of extra goodies.

Joe Armstrong (creator of Erlang)

From here on out, I’ll assume that you’re well acquainted with Javascript, have installed Elixir, and want to learn something. If not, check out the installation guide or read about why functional programming matters until you too are “on the bandwagon.” 🚋

Modules & Objects

With ES6 came the class keyword, bringing with it more expressive constructors, getters & setters, and polymorphism! Prior language versions supported a different kind of inheritance using prototype.

Elixir doesn’t support either class-based or prototypal inheritance. Instead, you get Modules, which are more or less templates for data structures and collections of static methods.

Take this object in Javascript:

The same functionality could be expressed in Elixir:

A real-world example of this pattern in Javascript is the built-in Math object. You can’t create a new Math() (many have tried), but you can make use of its static properties (like Math.PI) and methods (like Math.abs).

It’s argued that the lack of objects makes Elixir less capable, but what’s lost in power is gained in simplicity. Functional programming is designed, in part, to save you from yourself. Just think, in Elixir you will never have a problem with this, because it doesn’t exist!

When you want to build complex functions out of simpler ones, you reach for composition over inheritance. Functions are first-class citizens in both Javascript and Elixir. That means we can assign, pass, invoke, and return a function by reference in either language. This provides a solid system for building composable units of functionality.

Functions Ride First Class

Functions are ubiquitous in Javascript. There are named functions which are declared with the function keyword, and anonymous functions which are assigned to a variable (most commonly written in arrow notation).

This trivial example does everything mentioned above:

  • Assign a function to the variable addTen
  • Pass a function theThing as an argument to doTheThing
  • Invoke a function argument, theThing
  • Return a function as the result of getAddTen

P.S. the last technique where one function returns another is called currying.

All of this is possible in Elixir as well:

Although Elixir uses different syntax, both languages support named and anonymous functions that can then be passed, returned, and invoked. Next we’ll see how to build complexity by combining functions.

Method Chaining & The Pipe Operator

The way to write shorter code is by using the pipe operator. – Ryan Bigg

Method chaining is another common technique in JS. In its simplest form, it involves consecutively invoking functions on the same object.

Arrays are one common use case:

We can do the same thing in Elixir using the pipe operator:

The pipe operator |> takes the result of the first expression and passes it as the first argument in the next, reading from left-to-right, top-to-bottom.

(The pipe operator is so well liked that there is a proposal to introduce it to future versions of Javascript and Typescript! It is also supported with Babel plugins and as an experimental feature in Firefox)

However, when composing functions you often need only part an input–usually a certain property from an object or element in an array. That’s where destructuring comes in!

Pattern Matching & Destructuring

On the surface, pattern matching seems like a foreign concept, but put simply pattern matching is not assignment and it allows developers to easily destructure data.

Destructure… destructure… where have we heard of that? Oh yeah, ES6 brought with it a very similar feature called destructuring assignment!

This can be achieved in Elixir using pattern matching:

Both languages support extracting properties from maps and accessing lists values by position, although admittedly the Elixir version is more verbose. (note: there are tools to like the ~M sigil for more concise destructuring).

However, the irony of passing objects by reference soon sets in. In Javascript, if you want to create and modify a deep clone you’ll often see code like:

let newData = JSON.parse(JSON.stringify(oldData));

This is neither idiomatic or efficient, but without importing a library this is by far the simplest way. If this seems frustrating, that’s because it is. That’s why many languages and frameworks are moving to immutable data.

To Mutate, or Not To Mutate

In Javascript, objects are passed by reference. That means it’s possible to reassign arguments, leading to side-effects. Some frameworks like React try to save us from ourselves by enforcing categorically immutable data structures. That means every call to setState creates a new state object.

Here it is unclear whether fill operates in-place or returns a new array:

What it actually does is a bit of both! It reassigns values in the input array, which it then returns. This fails subsequent expectations of using this function to transform one array into a new array.

In Elixir, all data is immutable. That means variables are passed by value. Because of this, it is not possible to reassign the value of arguments nor is it possible to modify data in-place. Recall:

Functional programming is designed, in part, to save you from yourself.

— Me, earlier in this article

This ensures that functions cannot modify their input directly. Instead, they unambiguously return new data based their input.

Clearly, functional programming is the best programming! Ok, that is a bit of a stretch. Hopefully I have convinced you that functional programming is at least useful, and that Elixir is a cool functional programming language.

If you find Elixir cool and want to learn more, here are a few resources:

That’s it! Hopefully this primer helped demystify several basic concepts shared by Javascript & Elixir. Please feel free to comment and ask anything!

Follow me on LinkedIn · GitHub · Medium

Load More Related Articles
Load More By john
Load More In Javascript

Leave a Reply

Your email address will not be published. Required fields are marked *

Check Also

Why you should probably be using a design system (and how to build one)

Steps to scale-up your UI as a developer Perhaps you’ve heard the whispers amongst the mar…