Early Impression of Elm
Tags: programming.elm
Recently I wrote some Elm-lang code as part of a casual side-project.
The Elm program was simple, though non-trivial.
The program was a UI for making notes from emails. The Elm
program presented a list of emails for the user to select,
and let the user CRUD a note for the selected email.
Some changesets:
- https://github.com/rgoulter/simple-email-data-tool/pull/1/files
Initially adding the Elm program with Travis-CI config, RSpec
spec with Capybara, and the Elm program.
- https://github.com/rgoulter/simple-email-data-tool/pull/5
Changing from a <select/>
to a <table>
for one of the widgets.
(I was surprised by how easy this change was).
- https://github.com/rgoulter/simple-email-data-tool/pull/6/files
Adding keybindings to the input.
- https://github.com/rgoulter/simple-email-data-tool/pull/8/files
Adding date filtering, using a third-party pure-Elm library.
Where I’m Coming From
I’d be lying if I said I was very experienced with front-end code. e.g. I can’t think of any big mistakes I’ve made and things I’ve learned from said mistakes. The basics are straightforward; and a deep understanding of front-end web development requires an appreciation for all aspects of how a web browser works, which isn’t easy.
On the continuum of ‘liberal programmer’ (“if it breaks, just fix it”; likes Python, Ruby) to ‘conservative programmer’ (wants to know if it works at compile time; likes Haskell) I’m towards the ‘conservative’ end.
- I’m inclined to like Elm.
What I Didn’t Like About Elm
I was surprised that some things in Elm were (much) harder than they would be in JavaScript.
- I wasn’t able to figure out how to nicely access the query
parameters of the URI. (I ended up getting something which could
access the query parameters at a specific path; but I couldn’t
figure it out for any arbitrary path). This is an example of “easy
in JavaScript, hard in Elm”.
- While I found this frustrating, I
think the Elm-lang documentation makes it clear why it makes
this kind of thing ‘hard’.
- Elm is all about removing footguns. In this case, easy access to the window’s URI query params would introduce impurity; so, to access window’s URI your Elm program also need to ‘manage’ the URI.
- But I would anticipate further “of course that wouldn’t be straightforward in Elm” when considering Elm as a language.
- While I found this frustrating, I
think the Elm-lang documentation makes it clear why it makes
this kind of thing ‘hard’.
- I wasn’t able to figure out how to nicely access the query
parameters of the URI. (I ended up getting something which could
access the query parameters at a specific path; but I couldn’t
figure it out for any arbitrary path). This is an example of “easy
in JavaScript, hard in Elm”.
e.g. I wouldn’t wanna write this blog website’s page with Elm, since the Elm runtime is JavaScript; so if I used Elm then it wouldn’t be accessible to users with JavaScript disabled.
I still have to look into idioms or idiosyncracies about combining modules together. I’m not sure I ‘get’ it, or if the approach I took was stupid or fine.
What I Found Interesting About Elm
- The Elm Architecture. The restricted nature of Elm’s code means
that, while code still doesn’t magically end up well designed, it
still ends up being somewhat (or close to) idiomatic.
- My experience with GUIs other than Elm has been with languages that allow you to more/less update the code’s state from anywhere.
- With Elm, you have a ‘model’ Algebraic type, a ‘message’ Algebraic
type.
- Anything the Elm program needs to care about goes in its model.
- Any ‘action’ that might happen in the Elm program is represented by a message.
- The only place the model gets changes is in its update function.
- The only way effects happen is through messages.
- The question becomes “what nouns, what verbs do I want in this system? What is each noun? What does each verb do?”.
- Because of that explicitness and lack of mutation, edge cases (and race conditions) are surfaced.
What I Liked About Elm
It’s not JavaScript. Programming in JavaScript is .. fine. But I don’t particularly like JavaScript. It feels very blobbish.
95% of the time it’s a joy to write in Elm. (Most of the time it’s not a joy to write in are the times when you’re trying to do something which would be easy to do in JavaScript. Or with impurity like time/randomness).
Elm mostly has the “if it compiles it works” aspect to it.
Elm programs/modules are self contained and small.
- Everything you need in a module must be explicitly imported.
- The lack of mutation means things are much more explicit.
Elm’s record syntax is nicer than Haskell’s.
My Development Experience
I mocked the API that my Elm program would call with simple Ruby’s Sinatra servers.
I wrote RSpec specs which would compile the Elm program before running Selenium tests against the Elm program.
My program wasn’t sophisticated enough to need much development work on components individually. But I did find it easy enough to use “elm reactor” (compiles + serves the Elm source) to focus on one component at a time.
I developed my Elm program using Emacs. The most popular elm-mode gave me syntax highlighting. I didn’t feel the need to make use of elm-mode’s other IDE features.
- For code completion: I developed my Elm program on Windows. There’s an Elm language server. Unfortunately, I think because Windows is slow at launching processes, I found it was too slow for me to use with Emacs on Windows.
I didn’t make good use of it, but there is support in universal-ctags.
Would I Use It?
After having used it for a side-project, without the burden of needing to ship something reliable by some deadline:
Yes, I’m quite happy with the experience.
Obivously I’m interested in liking it, though; and this wasn’t
a high-risk project, so:
What situations/cases would I not recommend using it for?
- Projects which benefit from a rapid prototyping/delivery
(e.g. code maintainability/quality can be traded off) by an experienced team
which lacks any experience Elm.
- Projects which already show evidence of some kind of a
“lava flow” antipattern, or projects where using Elm is likely
to lead (or contribute) to an anti-pattern like this.
- Projects where Elm is chosen without consideration for
‘Choose Boring Technology’.
- If I were given responsibility to maintain some front-end
application code which was poorly written in JavaScript using ReactJS:
- While it’s possible to interop Elm and JavaScript,
I think the complexity of the same maintainers mixing the code
would outweigh benefits of using Elm.
- etc.
I think websites would be better maintained if they were developed with the discipline that Elm does a lot to help.