Quote: “We want to do our best work, and we want the work we do to have meaning. And, all else being equal, we prefer to enjoy ourselves along the way.” - Sandi Metz
As programmers, we pride ourselves in building easy-to-use and robust software programs for solving the thorniest of problems our users face. However, building good software that not only solves today’s problems, but also adapts well to the future requirements, is hard. Really hard. This difficulty isn’t due to lack of tools that enable us to ship highly maintainable programs. For example, the programming languages in the ML family such as Haskell and OCaml are well known for making it almost impossible to cause errors in production. The compilers for these languages catch almost all errors that plague programs built using other languages that are not as strict.
It stands to reason that all programmers should then be using languages from the ML family. After all, who doesn’t want to build programs that are error free? The reality actually is quite the opposite. Take a look at the results from a survey conducted by Stack Overflow in 2019 for the most popular web frameworks used by programmers.
The three most popular web frameworks — jQuery, React.js, and Angular — all use JavaScript. None of the languages from the ML family are in the list. Programmers are a smart bunch. Why then are they using languages such as JavaScript that have no built-in safeguards to prevent errors from happening in production?
One reason could be because the languages from the ML family are more suitable for building back-end systems. Front-end programmers are responsible for the code that runs in the client (typically, a web browser), as opposed to the server. Because web browsers only understand JavaScript, that makes it hard to use other languages. However, there have been multiple efforts to bring the robustness from the ML family languages to front-end development with projects such as Fay and GHCJS that compile to JavaScript a web browser can understand. Yet the front-end programmers don’t seem to want to use them.
Another reason could be because the languages from the ML family are hard to use. They are notorious for having a steep learning curve. In contrast, someone who has experience in HTML and CSS can learn how to add JavaScript functionality to their web page in a matter of hours. JavaScript is easy to get started with and thus highly usable. However, large programs written in it can be a nightmare to maintain. Programmers tend to write mountain of tests to prevent JavaScript programs from misbehaving in production. They also use elaborate architectural patterns to make adding new features to their apps less painful. What we need is a language that not only provides the robustness inherent in languages from the ML family, but also is highly usable like JavaScript. Elm is one such language.
Elm is a functional programming language for building front-end web applications. It brings the best of both worlds when it comes to building highly robust applications with ease. Besides maintainability and usability, Elm provides a plethora of benefits that are not present in most mainstream languages such as immutable values, stateless functions, type inference, pattern matching, automatic code formatting, and a great debugger. We will explore each of these concepts in detail in chapter 4.
Finally, Elm provides a novel architecture for organizing code which makes managing data flow between various components a breeze. Most other languages don’t come with one canonical way to organize code like this. We often have to compare and contrast multiple frameworks which is confusing and time consuming. Elm makes that decision for us so that we can just focus on solving the problem at hand and not worry about how easy our program will be to change in the future. We will cover the Elm Architecture in detail in chapter 5.