At the ‘Elm of Functional Programming
In this blog piece, we put the spotlight on one known as Elm and reveal why it’s definitely a one-to-learn for any serious developer.
What is functional programming?
Functional programming is a programming paradigm that has almost no common ground with traditional programming paradigms like imperative or OOP. Learning FP is like learning how to program from scratch. You will need to erase all previous knowledge of programming in general. Function in FP takes a different approach from the imperative counterpart. Back in imperative, you used to write several statements, changing different fields, getting data from different services, all in one method. In functional programming, you only have what you’re provided (parameters), and you only have practically one expression to return a new result. Everything is expressed as y = f(x) where f(x) is a function or a function composition. Functional code is extremely reusable because each function only has an input and an output without any side-effects. A programming language designed from the ground up as functional programming always bear two hallmarks: functional purity and data immutability.
In FP, a data model never mutates. Instead, a copy of that data is constructed with new values in place. Data immutability guarantees that ‘modifying’ an object will not introduce any undesired effect on other components that rely on the current instance. All FP languages enforce data immutability, whereas it’s very hard to do the same thing in traditional non-FP languages. The main reason for that is object referencing. Objects in traditional languages are not copied, they are only used as references. Any modification made on one copy is reflected on other copies, thus you can’t guarantee that your object will not be modified although your code doesn’t do it automatically.
Reading an FP script without prior knowledge can be intimidating. Consider the following function for instance:
There are two components in this: a function declaration (like a header in C) and a function definition. The first line defines a function name maxId, which receives an array of Todo objects and returns an integer. The second line is the function itself. The whole function is a composition of three different functions: List.map, List.Maximum and Maybe.withDefault. The "|>" character pipes the result of the previous function into the next one, thus making the data flow much clearer. If we’re not using pipes, the function can be written in a traditional way:
So what is Elm?
Runtime: ~29KB gzipped
SSR support: not yet.
Strong static types → finding errors fast with readable compiler messages
No null or undefined → impossible to leave possible problems unhandled
Immutability & purity → readability and maintainability
No runtime exceptions → uncomparable reliability
Reactive by design → FRP isn't opt-in, it is baked right in the language
When talking about Elm as a language, you will literally not be able to get a runtime error, ever. There’s no null. If an expression can or cannot return a value, it will either return a Maybe or a Result. A Maybe can be a value (Just x) or a Nothing. It’s just like a nullable data in other languages, but in Elm the compiler forces you to handle the Nothing case all the time. In fact, you never use a value inadvertently without checking for null, or writing a code without handling the exception (although there’s no exception in Elm, there’s Result). The typing system is extremely strict (there’s nofallback; and yes, I’m looking at you Typescript). All standard FP features are supported (function composition, immutability, function purity). And it’s much easier to learn compared with Haskell or F#.
As a frontend framework, Elm performs admirably. It takes half the time to complete the benchmark compared to React and Angular 2. The browser support is standard fare (latest 2 versions, IE 10 and below need not apply). The runtime is small (29KB gzipped) and Elm compiler will do the rest for you.
But there are drawbacks…
Elm doesn’t support server side rendering. The support is on the Elm language backlog, so right now it only works on browser. Therefore, if SEO is important to you, don’t choose Elm. And although this FP language is perfect for building a single page application as well as progressive enhancement components, it cannot stand on its own if you need a universal application built upon frontend technology.
The world of web development is one of incremental changes. However, a revolutionary language like Elm will be difficult to break into the mainstream because - just like Haskell and other peculiar languages - they belong strictly in the domain of the enthusiast. The only advantage of Elm compared to the likes of Haskell and F# is its web root. It belongs to the web, thus the effort to build a product that can be evaluated is greatly reduced. The cost of investment is much lower, resulting in a lower barrier to entry. Personally, I don’t think many companies will adopt Elm as a primary programming language anytime soon because it still has a long way to go before it meets a range of practicalities; but one thing I can be certain of is this: Elm and its functional style will gently nudge developers into a better programming paradigm and thus, help them write better code, and seamlessly too; so much so that once you write functional code, you will never want to go back to the imperative style again.