One year with elm — What’s next?

Guillaume Hivert
10 min readFeb 5, 2018

--

Approximately one year ago (on the 15th of March to be exact) I shared my first feelings and thoughts about elm, one month after beginning working with it. Today, I think it’s time to do another recap since a lot of things changed in my everyday developer life.

First: elm changed my way of thinking

Literally. When writing imperative or object-oriented code, I was perpetually thinking on code. On syntax. On mutations. I was wasting a lot of time to check if my functions behave correctly. Writing a lot of tests, to ensure all cases were covered. There was ‘things’ everywhere in my applications, and I was often unable to explain what it was. I can’t count the number of times I checked the type of a variable in Ruby or JavaScript. When maintaining 6 months-old code, finding types and behavior was way more harder than expected. I was focused on things which, finally, don’t have any added value in my work. I am writing code, not for me, but to provide something useful to my clients/my users, and every day spent to understand code, because of lack of types or documentation is a lost day ; a day I could do something useful.

Yes, maintaining code is complicated…

I don’t want to think about code, I want to think about concepts. As a developer, I’m manipulating data structures, algorithms, etc. Those things are not ‘code’, those things are concepts. Functional programming makes it easy to manipulate them. I don’t need anymore to loop over a list and apply a treatment to each element, while checking the range. I’m mapping some values to some other values. Just like in a maths world. I’m thinking functions and sets. Maybe it’s because of my studies — you know, in France, we’re doing so much maths at school ; and maths are our way to select the best students whatever you do in your life — but I find it way simpler. I can conceive my programs as simply as a sequence of transformations on sets, with help of pure functions. There’s not really code anymore, there’s basic building blocks that I’m manipulating.

If you‘re more familiar with object world, your building blocks are the objects. Smalltalk do it great: everything is an object. You’re sending messages to your objects, and they’re supposed to do something. You can even send messages to integers or strings. You talk to them. ‘Hey you, the string! Gimme the next subchain of yours, which contains this particular regexp!’ And it works the same way, whatever you’re doing. You’re building your own building blocks by thinking about living entities and the message you can send to them. You finally hide everything else, to be sure anyone will not be able to use the object in other ways than the ones you provided. Encapsulation is the key. But when you’re the user, you send messages to those objects. And they probably will do something. Or not. Maybe they will do something on their own. And it’s really tough to figure what’s going on under the hood. But, hey, when building my Eiffel Tower in Lego, I’m not using building blocks able to change on their own. I’m not sending messages to my blocks. I’m concatenating two of really, really dumb blocks. And that’s where resides the difference between these paradigms.

In functional programming I’m using dumb, easily understandable building blocks. I’m using those blocks to construct something bigger, just like the DNA — which is basically read-only quaternary-data encoded in your body — makes possible to produce proteins via ribosomes, and so, allows to build every form of life you can think of nowadays. And it’s almost always possible to dive into the structures I’m manipulating. And even when I need to do some side effects, I don’t need to do the dirty work: the language is here for me, guaranteeing me I’m not doing something absolutely crazy without sense.

That’s the main change in my daily life. I’m looking at every app or software for an overview of the project. I’m not dealing with problems and runtime exceptions, I’m looking for the big picture. I’m thinking in terms of models and transformations. I’ve learned how to divide things in modules by behaviors. And I discovered it changed the way I’m thinking on software architecture: blockchain, event-sourcing, etc. Those are concepts of functional programming, with data and behaviors, not mixed together in an incomprehensible way.

Second: elm learned me the web, the good way

When I started elm, I wasn’t aware about the web. I did some HTML/CSS/JS during my studies, but I’ve never made a real project. I was afraid about the web. On CSS, of course (because in my opinion CSS is both powerful and complicated at first), but also on JavaScript. JS always been something complicated. Prototypes were awful for me, the ‘this’ semantic is still obscure, and the DOM manipulation was terrible. JS was dense, complicated, and never warned me about what I did wrong. As a lisp-lover, I expected to find the same simplicity in JS than in lisp, as Brendan Eich took Scheme as one of the JavaScript inspiration. But I never found this simplicity.

Batman!

I wasn’t aware of the Virtual-DOM algorithm. I knew about it (even tried something similar with Yaw), but never experienced it really. elm was the first times that I used a Virtual-DOM. And this Virtual-DOM opened my eyes! But, where elm shines compared to React or Vue.js, it’s on the integration. elm is simply the best tooling you can find today in web languages. Everything you really need is packed in the elm-platform: no more, no less. When you need something more, you get a package manager, and an awesome community (with an awesome Slack!), building awesome things like Ellie. elm guarantees you on the ‘zero runtime exception’ as long as you follows its rules. And you have a powerful language, easily understandable, easily maintainable. I know React never made me the same ‘Wow!’ effect. React is a lot more complicated. You have to choose which reducer you’ll use before you even start to code. And you’re forced to write JavaScript code. The JavaScript community is splitted around technologies, where the whole elm community agrees to support one language, one technology.

elm allows me to learn about HTML and CSS easily. Defining interfaces has never been so easier. I didn’t care about DOM handling or weird behavior: I could just focus on rendering the good things. I could focus on learning at my own pace, HTML element after HTML element, CSS property after CSS property. I wasn’t overflown with so much things to deal with. That’s why I think it is the good way to learn web. Because learning web with JavaScript is awful. You’re always tempted to do bad things. You know the voice in your head, continually trying to convert you: “Come to the jQuery side… We have cookies.” or “Oh, look, some thing you could easily solve with just a little side effect, think about it…”. But that’s not how you end up with good, clean code. You’re only writing code resulting in a real nightmare to maintain in the future. You will just make people flee from the web world. In my university, web was considered like some of the worst thing in computer science, with bad habits compared to secured soft (hello Event-B!) or type theory, language theory, etc. In my opinion, it’s mainly because no one tried to do it right, because there was no need to. Today, with the advent of elm and other Haskell-like languages, it’s time to improve the image and quality of the web!

Third: elm taught me about code-reusability

Code-reusability is often both a sweet dream and a necessity. Few people want to rewrite a framework today. Even fewer people want to rewrite a language to create an application. Using a framework, libraries, etc. are needed in an everyday developer life. It decreases work and generally improves quality. But, as a developer, it’s often hard to build something generic and correctly separate coupled to uncoupled code in a codebase. Sometimes because the language itself can’t handle genericity (C, I’m talking about you!), sometimes because code is so complicated, and isolated from the rest of the world that it makes hard to see connections and redundancy. You probably know this moment where you see two similar functions in two separate objects. This moment where you have to think about your architecture. This moment where refactoring becomes painful.

The real power of elm is its compiler. The compiler warns you friendly when you make a mistake ; and even propose modifications for your code, which often work as is. It guarantees good refactoring and assures you that you’re not destroying your existing code. And the module system in the language doesn’t trap you for ever. Removing or splitting code is costless. You can easily refactor your code at any time, and don’t lose safety or working code. Because elm code is centered around data structures, your functions often work with data structures, and resides in the same module. Sometimes, you can abstract your code, and make it work in a generic way. And you can easily reuse your code everywhere, because everything in the world is about data structures. Abstracting data structures is the key to create powerful reusable abstractions.

Fourth: elm instructed me about powerful abstractions

And that’s elm learned me the most: creating abstractions. I understood you can build abstractions as soon as you change your point of view. Think about data model, think about your business logic, and try to abstract most of what you’re repeatedly writing or using. That led me to elegant and bodybuilder. Starting from HTML and CSS, I wondered what missed me in elm. What I was always writing in all of my apps. The answer was so evident: CSS. I was writing so much lines of inline styles directly in elm, and so much CSS code in CSS files… I needed something more powerful. That’s where I understood what abstraction was necessary: I was avoiding HTML with elm, but not CSS. I needed a tool to avoid CSS too. That’s how elegant came to life.

elegant is the perfect illustration of those powerful abstractions. Web is centered on separation of concerns of content, style and logic (HTML, CSS and JS). But, with the time going on, the frontier between content and logic reduced, to finally disappear with recent frameworks. But the frontier with style is still here today, and it makes impossible to abstract or reuse CSS code. When you’re starting a new application, you’re starting new stylesheets. Even when you reuse components today, style is a real pain. How could you adapt the component to your style? Are there some classes on your HTML tag? Are styling made directly inline? And, how could you guarantee consistent styles on your elements? elegant is our answer with Thibaut Assus. elegant type checks styles, and make sure your not using inconsistent styles. BodyBuilder ensures this by forcing some styles on some elements. Style becomes a state in elm, and styling becomes functions. With those abstractions, styling elements is just like using elm libraries.

This is a real game changer today. In my app, I don’t need to rewrite some CSS code over and over again. I can just package my code, import my module, and I’m done. My style now relies with my content and my logic. I can change it as easily as changing a variable in my code. I don’t have to rely on CSS weird rules and remember what rules are incompatible: I just have to follow the compiler. And I can easily ensure everyone will correctly use my components when sharing it! Just defines what style the developer can use in the component, and you’re good! He/She will not be able to change the display, modify the font-size, or whatever! You can build strong abstractions, reuse code, and improve your daily-life!

If you’re interested, I let you explore what the package can offer as it packs also a full router able to do some transitions between your page, it uses a VirtualCSS to handle CSS in the same way VirtualDOM handles DOM in elm, it makes possible to uses hovering in inline style, and many more!

So what now?

My journey is only beginning! There is so much more to discover, and so much things to do! I’m extremely excited to see how the world will adopt functional programming! I’m sure it will change the world, and I think it’s important to onboard now. Even if you are not attracted by functional programming, I can only encourage you to try it, and build something great once. You’ll discover a whole new world like I did, and it was a total life-changer!

Fretlink is switching to Haskell when Microsoft is pushing F#. Facebook uses a lot OCaml while PureScript is getting more maturity to be used in production! Regarding elm, the ecosystem is still growing, and more and more people are interested in it, will use it, and will build great things! I can’t wait to see what the future holds!

I will for sure be at elm Europe this year again, and I’ll be so happy to discover the world community! I hope to see a lot of elm enthusiasts there, and you’re welcome to the elm meetup in Paris, if you’re coming to discover the city!

--

--