BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage Articles Elm in Action - Book Review and Q&A with Richard Feldman

Elm in Action - Book Review and Q&A with Richard Feldman

Key Takeaways

  • Elm in Action teaches developers the Elm language along with a new approach to coding frontend applications based on the Elm architecture.
  • Elm is a functional language with a simple, sound type system that guarantees the absence of runtime errors.
  • Elm has also strong type inference, resulting in developers largely eschewing writing types.
  • Elm can interoperate in a type-safe way with JavaScript through flags, custom elements, and ports.
  • There is no shortage of Elm developers. In fact, the offer outgrows the demand, making it easy for companies to hire.

The book Elm in Action by Richard Feldman provides a gentle, nonetheless thorough introduction to Elm for web developers, as they walk through the creation of a full-featured photo-browsing application. Elm is a purely functional, domain-specific programming language for creating web applications.

InfoQ interviewed Richard Feldman on the purpose, target audience, and content of Elm in Action.

InfoQ: Can you tell our readers about you? How did you get involved with Elm? How are you involved with Elm today?

Richard Feldman: In 2014, I saw a post about how Elm was using a virtual DOM. Prior to that, a friend had convinced me that it would be worth my time to try using a pure functional language. I was interested in doing front-end development and at the time, there was no pure functional language fit for front-end development. I was using React around that time (in 2013), and I was looking additionally for a language that would feature a virtual DOM. Elm checked all the boxes.

I tried Elm by rewriting one of my side projects that had a lot of maintainability problems. I fell in love with Elm, started to use it more and more, began going to meetups, and later tried using it at work somewhere in 2015. With Elm, we managed to solve a thorny problem that resulted in slow iterations, and, from that, we started using it more and more at work. So, I have been using it professionally and as a hobbyist. I now have a number of Elm-based open source projects. I am a part of the Elm core team. I guess these are the results of what has been an incremental process.

InfoQ: What drove you to write this book? What is the target audience?

Feldman: The audience I had in mind when writing the book is basically myself in the past. It is the book I wish that I had when I was getting into functional programming. Back in 2015, when I started in earnest to investigate pure functional languages, the learning materials that were available for the languages I was focusing on were pretty academic with a lot of jargon. They generally made erroneous assumptions about my background or interests (for instance, assuming an interest in mathematics or category theory). I wanted to build things and wanted good tools. My goal for this book was to make those really great tools available to someone that not only doesn’t have that theoretical background but wants to build things.

InfoQ: I made a quick search in Manning’s catalog and I found over 150 titles (from 2002 to now) with the series "X in Action." The popularity of the series seems to indicate a recognized need for readers to learn actively. How does Elm in Action achieve this?

Feldman: The book is designed to mimic the sort of real-life, in action work that you would do on a job, where you get requirements from somebody else and then you implement them. Chapter 2 to 8 is all about building an application, start to finish. Each chapter starts with a motivating use case, and at the end of the chapter, you will implement a new feature (or learn how to test a feature). Each feature request is conveniently set up exactly to be the right next thing to learn. By the end of the book, not only have you implemented a full-length application and made some revisions and changes along the way, (like you would in a real project), but you also have learned all the concepts necessary to build that application incrementally, one step at a time.

InfoQ: The book goes into the details of Elm -- the architecture, language, libraries, tooling, and runtime. But why learn Elm today in the first place? Concretely, what are three reasons to learn Elm? Elm’s website touts Elm as a delightful language for reliable web apps, I guess we have two already.

Feldman: The first reason is that Elm is the way to make the most reliable web applications you can. JavaScript and TypeScript are more popular ways to make web applications, but Elm applications have a reputation for seldom crashing. They also tend to be better at handling errors and edge cases. There is just a lot of upside when it comes to building reliable software. If this is something you care about, Elm is worth your time.

Reason number 2 is that Elm gives you best practices and good performance by default (for instance it generates assets that are as small as possible). You can hand-write JavaScript to be as fast as possible, and generate the least assets as possible, but as soon as you start using pieces of the JavaScript ecosystem, performance starts degrading. Elm is generally very fast. One benchmark comparing over 60 front-end libraries and frameworks shows that Elm generally tops the most popular frameworks (React, Vue, Ember, Angular). Another benchmark, based on the implementation of a realistic web application across 30 frameworks and libraries, showcases largely better asset sizes than Vue, React, and the like. Interestingly, in the latter benchmark, the top results are likely splitting code by routes, while Elm is doing none of that. Route-splitting has been on Elm’s radar at some point, but the dead code elimination being quite efficient, it does not seem to be a feature required by the community. As a matter of fact, we are at 400K lines of Elm code at work. So far we haven’t felt the need to resort to route splitting. It may come up at some point that we meet with such a large application that we need route splitting on top of asset minimization but we are not there yet.

Finally, Elm has a great reputation to be a really user-friendly language. This is not just in terms of language design but also in terms of the compiler, the way the error messages are expressed, the Elm’s community, and more. If Elm is something that you can use for your use case, and if you are building a substantial web application, it is by default a great solution for that. I think there is just a lot of joy to be had because of all those things.

InfoQ: Any reasons not to learn Elm?

Feldman: The number one reason would be if you are not building a web application. If you are building a content site, you may not need much more than HTML and CSS and a tiny sprinkling of JavaScript. I am aware that this is somewhat of a controversial opinion. There is an Elm package that would allow you to do static websites with Elm, in a way similar to Gatsby for instance. But I believe that if you are only doing primarily static content, you do not need the complexity of frameworks like React. So Elm may not be worth learning just for that use case.

A second and important reason relates to the fact that the job market for Elm developers heavily favors employers. When a company posts an Elm opening, it fills very quickly - that is like the opposite of the JavaScript world. There is an imbalance right now because a lot of people would like to be working with Elm. So if you are starting off your career, the most important thing you can optimize for is to get a job. That is not a great position to be in if you are starting off by learning a language where the job market is the way it currently is. But it is great for companies. If I talk about NoRedInk, I literally don’t remember how we ever hired anyone before Elm. After I was hired, we went two years before we successfully made our next front-end hire, and it was someone who joined before Elm. Pretty much all of the subsequent hires specifically joined to use Elm because there were not a lot of places where they could do that. If you start your career and you are looking for getting a foothold, any language that is not in the mainstream may not be a good choice.

The last reason not to learn Elm, at least now, is if the work you look to be doing is primarily gluing together off-the-shelf libraries, and you happen to know that those libraries exist in the JavaScript ecosystem with no equivalent in the Elm ecosystem. For instance, suppose you are looking to build something with charts. The JavaScript and Elm ecosystem both have libraries addressing charting. However, maybe you will find one particular type of chart that can only be found in the JavaScript ecosystem. If your job is mostly going to consist of gluing JavaScript libraries without much glue code or custom logic, you are not going to get a lot of benefits from Elm. The more code you are writing in Elm, the more benefits you get out of Elm. The reverse then is also true. So you must consider if Elm is the right fit for your project in the first place.

InfoQ: The whole book is pretty didactic about the Elm syntax and Elm’s recommended code formatting. From the first two chapters, the JavaScript developer understands he will have to get used to conditional clauses being expressions, passing parameters to function without parentheses (used for tuples), and with array items separated by commas on the beginning of the line (also dictated by conflicting Elm syntax). In your experience teaching Elm, how easy is the transitioning to Elm for JavaScript developers? What are the more surprising aspects of Elm syntax and formatting from a JavaScript perspective? The nicest?

Feldman: The most surprising things about the syntax include the comma placement. There are specific reasons for that and I believe they are explained in Chapter 1 of the book. There are more things that may be surprising (like not using parentheses in function calls) as you mention but honestly, in my experience, people get accustomed to the new syntax in matters of hours.

I have on several occasions taught an 8-hour Elm workshop and by the end of the workshop, most of the class is already used to it. The things that actually take the most time to get used to are the architectural differences vs. frameworks like React for instance.

InfoQ: TypeScript developers may enjoy a much simpler type system in Elm, introduced in Chapter 3 (Compiler as Assistant) of the book. Can you elaborate on the key differences in type systems between Elm and TypeScript, and how that benefits the creation and maintenance of web applications?

Feldman: Elm does not have the type any. The type any is sort of an escape hatch that is important to facilitate TypeScript interoperability with JavaScript. It may however lead to runtime type mismatches. The TypeScript type system is intentionally unsound. That may lead to crashes and worse things.

Elm’s type system is sound - it does not have any. All of your Elm code and also all of your dependencies is fully type-checked with no exceptions and no escape hatches. Elm/JavaScript interoperability is specially designed to preserve that. You can always have a very high degree of trust in your code. Almost always when the compiler is satisfied, the code works. The degree to which that is true with TypeScript is much less.

Second, Elm does not have sub-typing. The Elm type system is smaller. There are way fewer concepts to learn. By the end of Elm in Action, you already learned 99% of the Elm type system. You can learn the entire type system in a beginner book. In fact, only Chapter 3 in the book focuses on types.

Then you never have to write type annotations. You can just write your code and if the compiler hasn’t been told by you what the type is, it will figure it out. I don’t introduce type annotation until Chapter 3 in the book, and yet you have by then a fully working application. That was an intentional choice for me as a teacher. I believe it is easier to learn types in the context of something you have already built rather than having to learn the types first.

Some language features do require that you declare types. Ports for instance require types, as that is the whole point of ports. You receive data from JavaScript and the compiler can’t figure out the shape of that data by itself.

InfoQ: By the end of Chapter 3, the reader has developed a simple client-side photo application. Chapter 4 and 5 fully introduce the Elm architecture, including view and update functions, commands, and subscriptions. The simple application from the previous chapters grows in complexity as the support offered by the compiler for refactoring purposes is made clear. The mentioned chapters additionally illustrate communication with JavaScript, which revolves around two strategies: ports and custom elements. The latter is quite fundamental as, on the one hand, reusing existing libraries is a key productivity factor, and on the other hand, there may not be another choice because some functionalities are simply not implemented yet in Elm. Can you explain succinctly to our readers what ports and custom elements are, why they exist in the first place, and what use cases they cover?

Feldman: Custom elements are not an Elm concept - they are a web standard implemented in most browsers. Developers can write custom elements with JavaScript that work like any other HTML element. Custom elements can be created by Elm just like any other element. They are thus a very good way to include third-party JavaScript libraries that update the screen, for instance, a charting library.

Flags allow developers to pass data from JavaScript to Elm on startup.

Ports link to commands and subscriptions. Both of those are useful when you don’t need to do anything on the screen. You just need data in and out. For instance, we used to use a JavaScript analytics library. We would just send a custom event through a port to the analytics system. Similarly, events or data can also be sent from JavaScript to Elm through subscriptions.

InfoQ: Chapter 6 dealt with testing. The Elm architecture relies on two key functions which will describe most of the logic of the application: update and view, both of which are pure functions so any function used by them is also pure. Unit testing is limited to checking that the right input fed to a function produces the right output. Testing the view is similar to testing a data structure for its content, and Elm provides dedicated querying utilities to that purpose. Two techniques are described: example-based testing, and property-based testing. Property-based testing randomly creates a series of tests based on a provided generative template. Elm also allows testers to interact with the data structure representing a DOM view: events can, for instance, be simulated and the triggered runtime messages can be checked. Chapter 6 provides nice examples of testing the immediate outcomes associated with user interaction with the app (for instance event click simulation). How would you go about checking larger user scenarios, which involve a series of user interactions? Imagine a wizard form with several steps, each step corresponding to a different screen.

Feldman: Any testing tool that directly interacts with the browser can be used for testing. At work, we use Cypress. Other companies may use Selenium. Those techniques don’t work differently when using Elm. The advantage of the techniques I focus on in the book is that they execute much faster.

InfoQ: The last chapters (7 and 8) continue to illustrate Elm syntax and techniques by adding and implementing features to the photo application the reader started to implement in the first chapters. Chapter 7 features dictionary and tree data structures, recursive data types, and decoders. Chapter 8 features single-page application (SPA) routing and navigation. Contrary to other chapters where Elm was controlling one DOM element of a page, in those chapters, Elm controls the whole browser page and navigation. With this, the reader has been taken from a simple application to a full-fledged SPA, and in the process, was exposed to the Elm syntax and Elm patterns for developing reliable web applications. Appendices deal with setting up an Elm environment, installing Elm packages, and other practical tools.

I believe Elm was first introduced in 2012. That was a much different Elm than now as is logical given the 8 years in between. Signals were dropped in 2016 and I wonder if anybody still remembers them. The Elm architecture which includes view and update functions, commands, and subscriptions, was introduced as a replacement and has since been replicated across several languages and frameworks - to the point of having a dedicated acronym (TEA). The REPL, CLIs, runtime, compilers, asset bundlers have all improved over the years. What is Elm missing for its 1.0?

Feldman: It is not that Elm is missing any particular feature. Evan Czaplicki, Elm’s creator, thinks of a 1.0 version as a commitment to stability and backward compatibility. There are still more breaking changes that Evan intends to make. Having said that, the breaking changes have become milder and spaced over time. 0.17 to 0.18 resulted in small breaking changes only. Breaking changes when migrating from 0.18 to 0.19 were even smaller than that.

But 1.0 means that enterprise customers or teams should feel very confident that they are not going to have things broken for a long time, and right now that is not an expectation they can reasonably have.

InfoQ: Given that Elm has still not reached 1.0, how strongly do you recommend using Elm in production today?

Feldman: Elm’s level of stability right now is such that I recommend it in the strongest possible terms for production as long as it fits your use case. It is the way to make the most reliable front-end stuff. To give a data point, React went from 0.14 directly to 15 to reflect how stable they thought the library was. I think it is similar with regard to Elm. It is very stable and Elm 0.19 is something I am more comfortable recommending than any JavaScript framework that is 1.0 and over.

About the Book Author

Richard Feldman is the author of Elm in Action from Manning Publications, the instructor for the Frontend Masters Introduction to Elm and Advanced Elm workshops, and a member of the Elm core team. When he’s not writing about Elm, teaching Elm, speaking about Elm, working on his Elm open-source projects, or using Elm professionally at NoRedInk, you can find him hosting the Philadelphia Elm meetup.

Rate this Article

Adoption
Style

BT