Why we should all use Elm

Published Apr 12, 2017

I wanted to write about Elm for a while, this article is mainly for people who are considering getting into Elm.

Javascript is simple, easy and awesome, you don't need a degree and just put a couple of lines together and boom it just works, you install node, download a framework like Angular or React, run npm and there! you're a developer! easy.
We can get away with a lot before the debugger tells us anything and frameworks give us an amazing array of tools strait out of the box to plan and execute a single page application effortlessly, but it all comes at a cost.

This cost becomes evident when our app gets really big and complex with lots of features and many entities.

The main issues arise from the elastic nature of Javascript: mutability, typeless system (functions), impurity (functions return value) and side effects.
To overcome these we started using Typescript, Purescript, Closurescript, ImmutableJS and Elm.

Let me touch on each of the aforementioned problems but first let me conclude that Elm is the only language that gives us a solution to all those problems and more. Let's also agree that the fact that we can throw almost anything at Javascript and it's ok is a bad thing in that we need a system that constricts us from doing things that might hurt us in the future.

I like to think of Javascript as silly putty compared to Elm as legos where you can't fit parts that don't go together.

Mutability vs Immutability

Taking the ability to mutate objects away from developers is an important step to insure we can't mess things up by mistake.
In Elm we have to create a new modified object.

Pure functions vs impure

Pure functions are functions that can only return a certain value i.e

getUserName(User) : String

can never return anything other than a string.

Type system vs typeless

Having a type system in combination with pure functions is a powerful combination freeing us almost entirely from runtime errors.

consider the following code:

let loggedIn = Users => Users.map(...

In Elm this will not compile unless Users is a declared type.

Also we cannot declare a function that doesn't have return value:

loggedInUsers : List User -> List User
loggedInUsers users =
  List.filter ....

Here we declare exactly what goes in and exactly what goes out.

If there are no logged on users we can't return anything other than a list of users so we may want to change our function signature to avoid returning bogus data:

loggedInUsers : List User -> Maybe (List User)
loggedInUsers users =
  List.filter ....

Now our function is ready to deal with situations where no one's online and will either return

Just onlineUsers

or

Nothing

This may seem troublesome at first but by returning a Maybe type we ensure we always get the result we want including no users, purity gives us confidence and less things to worry about.

Side effects

In Javascript we easily recognize side effects with parameterless functions with no return value like routing and asynchronous operations. Side effects are actions that happen in the background, we have little or no control of whats going on, it’s the “magic”.
The problem is when side effects have unexpected results it’s hard for us to figure out and time consuming to trace down. Once we do we have to do much boilerplate to handle mistakes we can’t foresee and more chances things can go wrong.
In Elm all side effects are handled by the runtime so it’s almost too easy to write code and refactor.

Conclusion

It took me a fair amount of time I think months to really get a firm grasp on how to think in Elm, this isn’t a tutorial, I just wanted to touch on some of the features Elm has that sets it apart from the other languages and why I think these features place it in a totally different league for front-end development.

Discover and read more posts from Asaf Cohen
get started