It’s true that Elm doesn’t have typeclasses, but I think what people are objecting to here is that your stated goal is to be objective, but your word choice consistently editorializes certain design choices as sacrifices - and many of us don’t see those choices as sacrifices.
Suppose you wrote “Isn’t it true that Python lacks direct memory management capabilities and has limited expressivity compared to C and Rust?” If I’m a Python fan reading that sentence, I wouldn’t say you’re lying, but I also wouldn’t use the word “fair” to describe that sentence as an objective assessment of Python’s design. It’s pretty clear from the way it’s written what the author’s preferences are.
You’ve implied several times in this thread that you see higher kinded polymorphism as an objectively net positive language feature which Elm has sacrificed for the sake of other benefits. In contrast, I see HKP as a net negative for Elm in the same way that I see direct memory management as a net negative - while understanding that both language features might make sense for other languages - so I don’t consider it a sacrifice for Elm not to have it.
Quite the contrary, as a longtime Elm user who understands how HKP works in other languages, I would be disappointed if it got added to Elm - for my own enjoyment of the language, setting aside the impact it would have on others. I almost laughed out loud when I read the word “should” in this sentence:
If you ask me, for Elm this is the best solution from a stylistical point of view.
I actively prefer List.map : (a -> b) -> List a -> List b
and Array.map : (a -> b) -> Array a -> Array b
and so on, to map : Functor f => (a -> b) -> f a -> f b
or Mappable
or any other name you might choose. When I started using Rust, I found Iterable
polymorphism using traits less stylistically appealing to me than Elm’s “containers do not share code in that way” style.
I want to be extremely clear about this, because your comments in this thread suggest more than a little skepticism that preferences like mine actually exist. Like only beginners could possibly feel that way, and all experts who learn how these features work will obviously embrace them as objectively superior.
I appreciate that you’ve taken the time to ask Elm programmers what we think about the language’s pros and cons. If you take only one thing away from the responses you’ve gotten, I hope it would be that there exist expert functional programmers who actively prefer Elm’s set of language features around polymorphism to Haskell’s, PureScript’s, etc, and do not consider it a sacrifice for Elm to have made these choices.
If you want examples of sacrifices Elm has made for the sake of other goals, I would look immediately to FFI. By forcing JS interop to go through strictly controlled channels that take more work than FFI takes in (for example) PureScript or BuckleScript, Elm has sacrificed adoption speed for the sake of reliability and long-term ecosystem strength.
Another sacrifice Elm has made is conciseness for simplicity and explicitness. Two often-requested features are Objects (that is, React components) with their own local mutable state, and JSON decoders automatically derived from type aliases. Both are language features that would let people write more concise code in certain circumstances, at the cost of (among other things) making that code less explicit to read and at the cost of making the language more complex. These costs have seemed unacceptably high, so in both cases conciseness has been consciously sacrificed for the sake of other design goals.
I see all of these as sacrifices worth making, whereas I don’t see HKP or direct memory management as sacrifices at all; I just think the language would be be worse if it had them.