Why Elm?
Submitted by Bill St. Clair on Fri, 19 Jul 2019 10:28:57 GMT
An AngularJS user in the Fediverse asked me to sell Elm to him. This is my first attempt.
I have never used AngularJS or any other JS framework besides jQuery, so I'm operating from a quick perusal of the Angular web site, making my comparisons mostly invalid.
Caveats
First off, you're going to miss a lot of Angular's features with Elm. Elm has a functional flavor to it, not the templatey feel of Angular. Your entire site, except for the initial HTML file that loads the elm-generated JS, is Elm. And Elm wants total control. With a couple of exceptions:
- You may load Elm into only a single DIV of your larger site, and use regular HTML/JS for the rest of it. This, so I've read, can enable incremental conversion to Elm, but I've never done it.
- Elm supports two ways to get to your own JavaScript code:
- Ports - a send/receive messaging mechanism to get JS data out of and back into Elm. Fully type-safe, since incoming JS data goes through decoders to bring it into Elm, and errors there must be handled by the functional Elm code.
- Custom HTML Elements - Since Elm's virtual DOM can support ANY HTML element, you can roll your own, to do anything you can dream up.
Elm's package manager is centered on open source, stored at GitHub. I've proposed a simple mechanism to open this up, so that you can easily define your own package plugins, or not use Microsoft's repository system, but Evan Czaplicki, Elm's creator, has not been open to the idea.
A normal way around this for organizations that need their code to be proprietary is a mono-repo for your code, and just include ths whole thing in every project. Elm's compiler is so fast, and so good at rebuilding only what needs to be rebuilt, and including in the output only what is actually used, that this isn't as bad a solution as it sounds.
Or, if you have Haskell chops, you could fork the Elm source, and add the package manager plugin yourself.
Advantages
Now that I've highlighted some caveats, on to Elm's advantages.
No run-time errors. Ever. If it compiles, the JS generated by the Elm compiler will contain logic errors that you need to find and fix, but it will NEVER mistakenly reference a null value or call an undefined function. This is remarkable to experience, for one accustomed to the runtime-error-prone JS environment. And it really works.
The same kind of type-checking that C programmers have had for decades, but without the necessity to say everything twice, and with a much friendlier compiler, and no way to get around the type safety (except in your own custom JS, as mentioned above). JS linters may give you a lot of this, but they don't do a complete job. The Elm compiler does.
As a long-time lisper, accustomed to run-time type checking, but compile-time laxity, I was surprised to find that I really like this. It takes a little longer to get your code to compile, but once you do, you know it won't fail because of a runtime error.
Refactorings, even large refactorings, are a joy, and usually "just work" once you get the refactored code to compile. In Elm, I'm not afraid to make radical changes to pieces of my code. This causes a large list of compiler errors early in the process, but you fix them one at a time until it builds, and then it usually works.
The generated JavaScript is not difficult to read, and is pretty good, performant code. You definitely lost a little in efficiency over hand-coded JS, but you can always move inner loops into ports if necessary, and it is rarely necessary.
Elm webapps behave pretty much like native apps. With all the JS frameworks available, this isn't as much of a sell as it used to be.
Conclusion
I wish I knew how to express my sheer joy when I program in Elm. If I had Shakespeare's skill, I'd write a sonnet. "Shall I compare thee to a summer's day?"
Comments (1)
Apparently, this whole
Submitted by Bill St. Clair on Mon, 22 Jul 2019 13:56:28 GMT
Apparently, this whole essay is misguided, since Angular JS has been supplanted with Angular, which uses TypeScript instead of plain JavaScript. I have never written TypeScript, but my understanding is that its strong typing does a lot of what Elm does for preventing runtime errors in the compiled JavaScript. TypeScript is NOT a functional language, so you'll still be bitten by all the side-effect problems that functional languages completely avoid, but the advantages of Elm over TypeScript are a lot less than Elm over plain JavaScript.
Edit comment