At QCon London 2017, Richard Feldman, software engineer at noredink and author of “Elm in Action” from Manning, explained how their decision to switch to Elm led to a 100,000 LOC system running in production with zero runtime exceptions since 2015. Here, we provide a brief summary of Feldman’s key points.
Elm is a purely functional programming language that compiles to JavaScript and fosters the use of immutable data and static typing for the creation of browser-based apps. Feldman recounts how they went full-scale with Elm after using it in smaller side-projects. In particular, after completing a few months long project using React, he realized that:
It would have taken so much less time to do this in Elm that in fact it would have more than accounted for the amount of time it would have taken us to ramp people up and to introduce this new technology to our stack and the end result would have been easier to maintain.
Feldman identifies a number of key factors that account for the increased productivity and reliability of using Elm:
- Ellie, the Elm Live Editor, is a sort of advanced REPL for Elm, providing a rich interface when you can write, compile, and render your Elm code.
- Elm does not incur the “one billion dollar mistake” of allowing
null
values to freely propagate through your system, and requires you to explicitly deal with them usingMaybe
values. - Elm enforces the use of a single immutable value to represent the state of the whole UI. No state is associated to individual components, as it happens in React, although the model need not be a monolithic value. Using the model, Elm assembles a Virtual DOM, which is then
diff
-ed with the actual DOM, so only the relevant changes are applied. This approach, which is also found in React, is able to preserve performance, while granting the simplicity of dealing with immutable values. - One huge benefit of representing the UI state as a single immutable value is the possibility of handling a sequence of UI changes through the sequence of immutable values associated to them. When compiled in debug mode, Elm allows to navigate through older UI states by simply clicking the corresponding model value. Additionally, it is possible to export a set of those values so other developers can immediately reproduce faulty UI states and how they were generated.
- Being statically type-checked is a big selling point for Elm, according to Feldman, making it almost always true that “if it compiles, it works”.
- A major factor behind Elm reliability is the way it handles JavaScript interoperability. Contrary to most of other languages compiling to JavaScript, indeed, Elm enforces a message-based approach, where JavaScript code runs inside a service. This ensures that the guarantees provided by static typing are not broken by untyped JavaScript code.
- Finally, the Elm package manager, while not so extensive as
npm
, has its own strengths. In particular, it only allows packages to contain Elm code – specifically, no binaries are allowed, which makes it much more secure thannpm
. Additionally, it only allows packages that build correctly and automatically enforces semantic versioning.
Overall, Feldman says, JavaScript has proven to be quicker to get something on the screen, while Elm ensures higher overall development velocity.
A final remark concerns one of the usual objections to using a language like Elm, i.e., the difficulty of finding developer to hire. In reality, Feldman says, using Elm gave noredink a twofold advantage: on the one hand, it made their job posts stand out; on the other, it attracted developers that were specifically interested in learning Elm.