I don’t agree with all the critics, but I wanted to share them to the lobsters community
I think Elm not being as powerful as Haskell is fine—it’s their choice and so far it’s working out. I also think it should become a community language instead of Evan’s PhD thesis and personal project.
Full Disclosure: having looked at elm only minimally, I very quickly decided that it was not for me and I have no plans of using the language now or in the future. (This is not meant to be unkind to the elm community, I simply wish to clearly establish my position up-front.)
Having thought about this for a long time, I am actually really glad that Elm does not have typeclasses and I hope it does not get them.
Despite my disclosure above, this opinion of mine does not stem from animosity towards the Elm community; rather, it is because of the role that I hope Elm plays.
I have one and only one hope for Elm: that it becomes a gateway drug towards powerful, statically typed languages which helps us, as a discipline, move past dynamically-typed languages.
As sotojuan mentioned, I believe Elm has always had the preference for removing powerful features from Haskell in favor of lowering its bar for entry. This makes it more accessible by its target audience who tend to be more familiar with dynamically-typed languages.
Now, if we assume that my hope for Elm’s role is a GoodIdea™, then it is actually imperative that Elm’s type-system reveal a lot of power to the programmer, but be insufficient to accomplish everything that they would like. This insufficiency provides an incentive for the programmer to eventually seek more powerful type-systems (e.g., Haskell, Idris, Agda, Coq, Ada, whatever). Personally, I think typeclasses are the perfect place to draw the line. Not only do typeclasses offer a nice capability for abstraction, they offer a benefit in Haskell that I deeply appreciate: the ability to completely remove overloading. Instead of overloading, typeclasses provide a very elegant and powerful solution for statically-enforced contracts and rigorous definition of the meaning of a given symbol/operator/name. It is one of my favorite features from Haskell (one which I sorely miss in Agda—my current language-affair of choice).
Many people are familiar with the notion of “Perfect being the enemy of Good”, but my statement above draws from a different perspective: that if something already exists that is generally “good enough”, it deters all efforts to make something better. I would paraphrase this sentiment as “‘good enough’ is the enemy of getting something better.”
Elm has interested several web-devs I manage as being an intro to statically-typed systems, and I can only hope that they do not stop there. If even one of them moves through Elm and discovers a want for more powerful, static type systems, I would call Elm a success.
I’m sure that will be the case for some, but not all (or even many) of Elm’s users. Elm has a very different target demographic: web based apps, first and foremost. The languages you have mentioned are not at all optimized for the web-first use case that Elm is (not to say things like GHC.js can’t run in the browser–just that the tooling, libraries and auxiliary concerns aren’t web-first).
As an Elm and Elixir user that predominantly built web apps both for fun and professionally, I’m in the opposite boat: I see very little need to move towards a more “powerful” statically typed functional language like Haskell (I’ve read “The Haskell Book”, and I enjoy it philosophically, but I don’t see the need for it in my professional career).
Therefore, for Elm to be the gateway drug you envisioned, the other platforms would also have to offer similar toolsets to accomplish similar tasks, or else it won’t be a gateway at all, but rather a bumpy platform switch (like any other).
that if something already exists that is generally “good enough”, it deters all efforts to make something better. (I think there is a quote that conveys this notion very effectively, but I was unable to dig it up.)
Perhaps you’re thinking of something along the lines of “don’t fix what’s not broken” (in that, things that aren’t completely broken, don’t get fixed) or “the squeaky wheel gets the oil”?
I’m curious about why people couple Elixir and Elm so often—they’re different languages. Nothing wrong with it of course, I’m just curious. Elm is typed, an ML, and doesn’t allow side effects. Elixir (like Erlang) is only as functional as it is practical to be: it’s just higher order functions and immutability. It’s also dynamic.
Does anyone know why they show up together so often? I would assume those who love Elm’s types would like to have a typed language in the backend.
Great question. I obviously can’t speak for anyone else, but for me, it’s a matter of pragmatism. I want a tool that’s built first and foremost for the kind of application I’d want to build, and Elm is such a tool for web apps. It has great compiler hints for common errors (much like Rust, but even more so), and like I alluded to in my GP post, its standard library is currently well suited for developing web front-ends.
I have also used React.js professionally and I also enjoyed it. The reduction of state and decoupling of concerns is a great pattern that I believe is helpful regardless of language.
Similar line of reasoning for Elixir. It’s built by one of the core Rails devs with a focus on building fault-tolerant web backends (though the language itself is general purpose enough, as are the libraries). In truth, I do miss the strong type safety that Elm guarantees from time to time, especially when I run into runtime errors that I know would not have occurred with Elm.
So that brings me to Haskell: I think I would enjoy writing in it, but practical concerns makes that nearly impossible, which is why I specifically said “I don’t see the need for it in my professional career” (with special emphases on professional).
There’s is a close to zero percent chance that my current company will adopt Haskell, and I don’t see many of the companies that will likely employ me in the future adopting Haskell as well. Whereas with the high profile WhatsApp Erlang server turning heads, I know there will definitely be a market for Elixir/Erlang experience down the road (with a few company that I respect already adopting Elixir/Erlang internally).
By the way, if it wasn’t for the fortunate fact that the Director of Engineering was a champion of Elm at my previous company, I would have likely passed up on the opportunity to give Elm a chance and gone down the React.js path. So perhaps the true reason is closer to “serendipity” than a reasoned out narrative that I tried to spell out above :P!
I’m curious about why people couple Elixir and Elm so often
It’s just a weird (indeed, baffling) overlap in the communities. I’d wager that it just worked out that people started picking up both languages at the same time, a few people wrote blog posts featuring both languages and the attention/enthusiasm snowballed from there.
The languages you have mentioned are not at all optimized for the web-first use case that Elm is
Indeed, though my answer would be that we need to create statically typed languages that do target the browser and have great tooling (I do not think Elm can serve this role well).
As an Elm and Elixir user that predominantly built web apps both for fun and professionally, I’m in the opposite boat: I see very little need to move towards a more “powerful” statically typed functional language like Haskell
That is unfortunate to hear (in my opinion). I feel like the work-flow that static languages provide (a kind of built-in red-green workflow to get the compiler happy, with a lot of work and guidance being done for you) and the safety guarantees and rigor that they can provide convince me that dynamic languages should be left behind. But I understand that this is a subjective standpoint.
No, the quote goes something like “the greatest threat to creating a better solution to a problem is a code base that already works well enough.” I tried for a while to find it, but I was unable to. I think my paraphrasing above is pretty accurate:
“Perfect may be the enemy of Good, but ‘good enough’ is the enemy of getting something better.”
I feel like the work-flow that static languages provide (a kind of built-in red-green workflow to get the compiler happy, with a lot of work and guidance being done for you) and the safety guarantees and rigor that they can provide convince me that dynamic languages should be left behind.
I do enjoy having compile time guarantees, and I really like working with Elm with its helpful compile-time warning/errors. And I think you’re correct that in an ideal world, we’d be leaving dynamic languages behind. However, as I mentioned in my reply to sotojuan, there’s a very small likelihood that I’ll have the opportunity to work with Haskell professionally (building web apps), and as such I don’t see myself being able to devote as much resource into learning/using it as I do other tools that I know would help me pay the bills.
The other thing that’s been nagging at the back of my head is that having used both types of languages (static vs dynamic), I can’t genuinely say that I make better or worse choices with either language, which leads me to a sort of programming-language-nihilism position…
A comparison between a pre-1.0 language and a language which hit 1.0 in 1990 is sort of unenlightening. Elm doesn’t claim to solve all or even most problems at the moment. Evan has told me he wants to see what sort of problems people encounter with the language and find the best solutions to them, not just grab ideas from other tools.
Solutions exist to the problems in this post.
elm-all-dict has two solutions to the Dict issue - AllDict allows you to pass in the ord function to use, while EveryDict works with all types a where a can be represented uniquely through toString.
Elm takes a very peculiar stance on libraries. Libraries which don’t have the blessing of Czaplicki himself allegedly aren’t allowed to be published.
This statement is invalid. Effect modules and Native modules cannot be published without being vetted. Other packages, which are pure Elm, can. The reason is simple - it’s so simple to mess up Native code that even those of us that write it on a daily basis rarely trust it. By only allowing pure Elm modules on the package manager, the code is safe and guaranteed to give no runtime exceptions except in the case of a compiler bug or Debug.crash.
If the author had joined the elm-slack at any point, they would’ve been told this right away :)
Elm does have some problems with boilerplate - I have been one of the most vocal people about this. However, there are perfectly valid reasons for not implementing type classes. For one, the large majority of Elm users only have a basic familiarity with FP or less. Haskell developers, Elm is not Haskell. If you seek something with a more powerful type system, plenty of alternatives exist. Blog posts with excessive swearing and over the top complaints are not going to change the course of the language. Valid use cases, examples, and research will help guide Evan to a reasonable language design.
I like typeclasses in Haskell, but I can totally see why Elm doesn’t have them due to its focus on being easy to learn (especially for people coming from js) and having good, helpful and specific error messages.
I really hope it’s possible to have good error messages also with type classes, but at least today, with GHC, they are very confusing for beginners. Since you could have a Num instance for strings, the error messages when beginners try to appending strings by using + is
No instance for (Num [Char]) arising from a use of ‘+’
expecting the argument to be a number, but it is a string
Can someone elaborate further on people needing approval from Evan to publish Elm packages? That sounds quite extreme, but I suspect that isn’t quite the full story? In the linked issue it says:
Ah sorry, packages with native bindings aren’t publishable without getting Evan’s personal approval, which I haven’t done.
Which makes me think this is only for packages that have native binding to JS APIs?
What a patronizing and off-putting article.