
Elm is Wrong - HappyAndHarmles
http://reasonablypolymorphic.com/blog/elm-is-wrong
======
ccapndave
Despite the abrasive tone of this article, it is true that Elm misses a
convenient level of abstraction (whether that be type classes, module functors
or whatever).

I spent the first few weeks of my first Elm project fighting against the
language, trying to emulate type classes, build abstractions, do things like I
would in other languages and generally having a bad time. Eventually, and with
slightly bad grace, I conceded to the current limitations of the language and
did things the Elm way, accepting that sometimes things are bit boilerplatey
and cumbersome.

Now my second large Elm project is currently in its first round of QA, and the
difference to similar projects in Angular or React is striking. There are no
(and I mean ZERO) runtime errors that have popped up during testing. When QA
find a bug, its instantly clear exactly where in the codebase the problem is,
and usually simple to fix. So far most serious issues have ended up ultimately
being consequences of a poor choice of design/modelling that, when fixed, has
ended up in a higher quality overall codebase.

Yes, things could be better, and I'm sure they eventually will be. We would
all like the kind of abstractions you talk about in your article, but in my
real-life experience it turns out that you don't need them to write powerful
and high quality code.

And hey, when these kinds of abstractions do arrive I'll just refactor my
code, and know that the compiler will tell me when its done. Imagine doing
that in Javascript.

~~~
masklinn
> Yes, things could be better, and I'm sure they eventually will be.

That's unlikely, it is not the direction Evan wants to take, and so far the
language has gone the opposite direction on purpose and by design.

> And hey, when these kinds of abstractions do arrive

Which they probably won't. Realise that the Elm platform is written in
Haskell, Evan knows about these features, he could have used them and he very
specifically avoided doing so. If you want these abstraction-building tools
you'll be much better off looking at e.g. PureScript rather than wait for Elm
to add them.

~~~
ccapndave
I disagree - I think that firstly Evan wants to implement the _right_
abstraction (which he doesn't think is traditional Haskell type classes), and
secondly its simply not a priority.

------
sametmax
I'm not particularly interested in Elm, but basically this post is about one
problem in the language. One. This doesn't make the language a pile of garbage
as the author seems to let you think.

I'm a Python programmer. I fully expect dict keys to be able to be arbitrary
objects. But after coding a lot in JS, I realized I could live without it.
It's nice, but it's not a show stopper if I don't have it.

Same goes here. Yes, typing is not as good as you wish it was, but Elm is a
young language, give it time to evolve. In the meantime, what about the
innovative things in it ?

~~~
Singletoned
> I'm a Python programmer. I fully expect dict keys to be able to be arbitrary
> objects.

I'm a Python programmer too, and I also fully expect dict keys to be able to
be arbitary objects, and I get really frustrated with the fact that they can't
be arbitary objects. They have to be hashable objects, and the hash function
refuses to hash certain objects that it has decided aren't allowed.

~~~
sametmax
Come on, how many time in your entire life did you need this ?

For set, it's a bit more annoying. But for dicts. twice in 10 years maybe ?

~~~
dkersten
After a few years of Clojure(Script), where immutability means you can use
almost anything as keys, I have found many cases where my python code would
have been simpler and easier if I could use arbitrary objects (and therefore
data structures) as keys.

I mean, its not a huge deal, but it adds up.

~~~
orf
> I have found many cases where my python code would have been simpler and
> easier if I could use arbitrary objects as keys

You can use pretty much anything as a dictionary key

~~~
dkersten
That's really not true[1]. You can only use hashable types, which excludes
dicts, lists and sets.

For example (tested on both python 2.7 and 3.4):

    
    
        >>> {{'a': 1}: 2}
        Traceback (most recent call last):
          File "<stdin>", line 1, in <module>
        TypeError: unhashable type: 'dict'
        >>> {[1,2,3]: 4}
        Traceback (most recent call last):
          File "<stdin>", line 1, in <module>
        TypeError: unhashable type: 'list'
        >>> {{1,2,3}: 4}
        Traceback (most recent call last):
          File "<stdin>", line 1, in <module>
        TypeError: unhashable type: 'set'
    

Objects inheriting from _object_ are hashable by default, but the hash is
based on the objects instance such that each instance will return a unique
value for that instance:

    
    
        >>> class A(object):
        ...     def __init__(self):
        ...         self.x = 1
        ...
        >>> a = A()
        >>> b = A()
        >>> d = {a: 1, b: 2}
        >>> a.x = 10
        >>> b.x = 10
        >>> d[a]
        1
        >>> d[b]
        2
    

While this makes sense for the instance stored in the dict (because mutability
would otherwise mean that they key changes values), I don't think this is
particularly useful. I rarely look up dicts by instance, but rather by value.
That is, I would construct another object with the same attributes and look up
by that.

You can, of course, implement your own __hash__ to make it work, but you have
to do it manually for any object you want it and most third-party objects
won't have implemented it so you'd have to monkey patch them.

Contrast that with Clojure, where all built-in data structures (maps, sets,
lists, dicts etc) work as keys out of the box.

[1] I guess its true in the sense that you can implement __hash__ to make it
work. But its not particularly easy or idiomatic.

------
chadaustin
First, let me say that I think Evan has done amazing work with Elm, and Elm is
a very interesting language on several fronts. It is a positive contribution
to the world, especially the idea that error messages can be great and
compilers and type systems are tools.

That said, I agree 100% that the ability to form abstractions is a critical
part of any language that hopes to become a tool that larger teams and
projects can adopt. Without type classes and convenient mutability, I don't
see Elm achieving widespread adoption. (That said, it could gain those
features in the future.)

I've been working on a language inspired to some degree by Elm but also by my
experience teaching Haskell. Haskell has amazing expressive capabilities and
type safety, but the unfamiliar syntax is a hurdle that many people don't care
to jump. To that end, we've designed Crux to have much of the expressive power
of languages in the ML/Haskell family, while being as familiar and lightweight
as JavaScript or Python. The idea is that it's something you can pick up
easily but it can grow with you and your project.

Some articles on the design thinking:
[https://chadaustin.me/tag/crux/](https://chadaustin.me/tag/crux/)

The website: [http://cruxlang.org](http://cruxlang.org) [It's a preview!]

------
boubiyeah
I don't believe in Elm one bit. it's been 4 years guys. I follow its
developement (it's not a hard thing to do after all, it's a snail pace)
because its creator is intelligent and there are a few nice things in it.

But as a practical platform to build real apps? No way. I mean you can build
apps with any tech, so of course people will try and succeed with it; but it's
just a bad choice.

Elm is impratical because you can't do anything with it. I loathe directing
attitudes in that field where everything moves fast
([http://www.martinfowler.com/bliki/EnablingAttitude.html](http://www.martinfowler.com/bliki/EnablingAttitude.html)).

Its creator is a bit on the control freak side and far more of a backend dev
than a frontend dev. The reactive framework (the Elm architecture) is full of
boilerplate and anything that was not forethought will have to be a metric ton
of more boilerplate or delegated to javascript via asynchronous ports (if you
have to hide the crap away in JS land because it's impossible to do in elm,
somehow it's not elm's problem). The elm community is minuscule and not always
great, doesn't embrace new approaches (the ones who do don't stay for long as
it's so frustrating) they're more like robots repeating "wait for Evan to tell
us how to do that. If Evan didn't say anything yet, you are taking big risks"
or "Evan is working on this particular problem, just wait 2 years"

Meanwhile we can build apps real fast with typescript, which in version 2.0.3
is a very capable and more than typesafe enough language.

bucklescript/Reason might be a good alternative to the very closed Elm
ecosystem too if like me you like ML.

I think where elm shines is as a simplistic language and sanitized environment
to teach people programming. That's about it. It's still in a state of a
"research language" (and it's good at it), but is not being marketed as such.

~~~
valw
Rejecting a programming language feature because you find it constraining is
just ignoring history. Arguments similar to yours have been used to dismiss
Garbage Collection, type systems, and even the use of high-level languages,
all of which were very successful precisely because they constrain the set of
programs you can write.

Also, why all the hate? As you said, neither you or the TypeScript community
have any reason to feel threatened by Elm, which nevertheless has had a very
positive influence on the mainstream JavaScript community (look at Redux).

The only impact your comment could have is discouraging the Elm community from
furthering its valuable research in the field of web development. Please write
constructively next time.

~~~
boubiyeah
There is no hate here. Elm's current objective is to go mainstream. I just say
it's not good yet. I agree with you, Elm is very valuable as a competitor.

------
glenjamin
This post starts off with an abstract goal - "use a custom type as a dict
key", and then goes off down a rabbit hole trying to create typeclasses and
make it work. This is despite prior knowledge that Elm has chosen not to
implement type classes.

The line from Evan, Elm's creator, has always been along the lines of "show me
a concrete actual use-case that you can't do without typeclasses", this
article fails to clear that fairly low bar.

The other elm article from the other day about select boxes did a much better
job of identifying that not having a way to enumerate Enum types is a bit
annoying.

~~~
tom_mellior
_> The line from Evan, Elm's creator, has always been along the lines of "show
me a concrete actual use-case that you can't do without typeclasses", this
article fails to clear that fairly low bar._

Translation: "I will never add typeclasses."

There is no _concrete actual_ use-case that is _impossible_ to implement
without typeclasses. What typeclasses make possible is an _abstraction_ over
concrete actual use-cases. That is, you can always solve individual concrete
actual problems with boilerplate. Typeclasses "only" give you the possibility
to write that boilerplate once and for all and reuse it for every concrete
actual use-case.

Evan seems to think that that's not worth it, which is a valid opinion to
hold. But it would be a bit more honest to come out and say it like this.

~~~
Skinney
Evan has several times said that he's open for typeclasses. Problem is that
they have a profound effect on the language, and so they have to be done
right. He doesn't know what the right implementation of that might be at the
moment, so he's waiting until he comes up with what the right thing to add for
Elm would be.

~~~
leshow
You think Evan is just waiting around for the right abstraction to dawn on
him? It's been years with not one bit of code written in the direction of
adding a mechanism for abstraction in the language (whether that be
typeclasses or something else)

~~~
Skinney
"Code is the easy part"

First you need to figure out what exactly the Elm community wants and needs.
Once you have a pretty good idea of that, you can start prototyping things.
Elm is still young, and the most pressing concerns for using Elm in production
is not the lack of interfaces/protocols/typeclasses, but stuff like debuggers,
which is what Evan is working on.

I'm sure we'll see some tool for ad-hoc polymorphism in the future, but not in
the short term.

~~~
leshow
Blind faith might be enough for you but I don't buy it. The original issue was
3 years ago.

------
chriswarbo
I do have some sympathy for the author's desire to have record extension
(re-)added, as that looks like a pure win, from my outside perspective. Maybe
there are concerns which insiders may be better able to spot, like losing some
reasoning ability.

As for typeclasses, I think Elm's stance is perfectly reasonable. Typeclasses
aren't a pure win, they have downsides too:

\- They couple the term level to the type level by allowing values to depend
on types. This makes it impossible to compile or interpret a program without
first checking/inferring its types. Static types _without_ typeclasses don't
have this problem; as far as I can tell this even includes dependent types
(which do their coupling the other way), as long as you don't allow some form
of typecase.

\- Global uniqueness of instances doesn't compose. If I have a perfectly
correct module A, and a perfectly correct module B, a module C might break by
importing both, due to overlapping instances. This has to be mitigated by
convention, e.g. not writing orphan instances.

\- Local reasoning can require knowledge of global properties. This is
especially true for things like code generation. For example, if I plumb
together two expressions, say `nub :: Eq a => [a] -> [a]` and `xs :: [b]`, I
can generate new requirements like `Eq b`. However, I can't just go ahead and
implement those requirements (e.g. generating an `Eq` instance for `b`), since
that will break if there's _already_ an implementation, floating somewhere in
the sea of imported modules. Packages like `ifcxt` can help, by allowing
lookups and fallbacks, but they're not a complete solution.

\- If more than one instance of a typeclass might makes sense for some type,
it's pretty much inevitable that APIs using the typeclass (e.g. `foo :: Bar a
=> a -> ...`) will gain extra functions for bypassing the typeclass (e.g.
`fooBy :: (a -> ...) -> a -> ...`)

There are probably more issues in the literature, but these are ones I've been
banging my head against recently.

Typeclasses are a great idea and a useful addition to the PLT toolbox, but
including them in a language isn't an automatic improvement: it's more of a
design choice to steer the language down a particular path, when other
languages may prefer other paths. Similar to using strict/non-strict
evaluation, or exceptions, or macros.

~~~
maxthegeek1
Record extension was removed because it allowed Evan to improve error
messages, and because he found that Elm's power users didn't use the feature.

------
b123400
I have some similar thoughts when trying out Elm.

Every function that a language support/does not support shapes the ecosystem,
and that is arguably as important as the language itself. With Elm, decision
making is done by a small group of people and they can be quite opinionated.

I started when 0.15 is out, amazed by how beautiful FRP can be, then it is
gone now. I cannot add / remove fields from dictionary, I cannot have multi-
way if. My code base is still simple, so I can get around it, but I really
enjoyed the good old FRP style. In JS, you can definitely choose your
favourite frameworks, but in Elm, there is no alternative, there is only a
single HTML framework `elm-lang/html`, if they decide to drop FRP, you cannot
escape! This also means choosing Elm is also choosing to follow Evan, you are
betting on a person.

I hope things getting better someday, we will have a standard JS interop that
allows people to make their own 3rd party frameworks in Elm. Competition makes
things better.

~~~
pka
PureScript!

~~~
b123400
I tried Halogen for a while and found it too complicated. I need to create a
type with 6 type params (something like `ParentComponentSpec s s' f f' g p`)
for embedding a child component! Also, most of the operations are wrapped in
monad, which ultimately bring me back to the procedural way of thinking.

~~~
mrkgnao
Pux is great!

~~~
b123400
Wow, I never heard of that! Thanks, will check it out :)

------
FascinatedBox
As someone who's written a language, the need to have a personal approval from
a founder before being published to the site stuck out to me more than the
typeclasses. I'd argue in favor of it, so long as the review is done in a
timely process. I can understand wanting a smaller number of high-quality,
reviewed libraries that are tested and shouldn't break.

~~~
danneu
The restriction only applies to native modules (modules that ship with
Javascript): [https://groups.google.com/forum/#!msg/elm-
dev/1JW6wknkDIo/H9...](https://groups.google.com/forum/#!msg/elm-
dev/1JW6wknkDIo/H9ZnS71BCAAJ)

~~~
leshow
If you want to write anything non-trivial in Elm you need to use native
modules though because the language doesn't give you access to any of it's
"magic"

------
jprzybyl
This post is _way_ too angry. The problem it describes is legitimate, but
still just a problem to be fixed.

Having the language maintainer need to bless packages with native bindings is
strange, though. Tag the packages so that people know they use native
bindings, then people can decide whether or not to trust them. You cannot
build an ecosystem through one person.

~~~
ultrasandwich
Like most angry rants, it ignores the fact that it kind of is a fixed problem.
[http://package.elm-lang.org/packages/robertjlooby/elm-
generi...](http://package.elm-lang.org/packages/robertjlooby/elm-generic-
dict/latest)

------
desireco42
I didn't do any larger projects, so far my time with Elm was enjoyable,
language and tooling is very good and interesting.

I don't like the tone of this article, otherwise critique seems to warrant
more discussion. Elm as a language is in development and community is very
vibrant and open... as long as you don't mention rules for formatting, one in
particular ;). So, I really wouldn't discount Elm so quickly.

On the other hand, PureScript and Reason also look very interesting and I am
looking forward to get more familiar with them. I think we live in fantastic
times.

------
dj-wonk
I enjoy Elm, and I think improvements are welcome. In particular, I would like
to see some improvements to the Elm REPL such as type inference and
documentation strings.

The article makes some great points; however, the title is not particularly
useful nor a good summary of the article itself.

------
iLemming
Elm is great and Purescript even better. I haven't though heard anyone
building apps using Elm on both back-end and front-end.

I have enourmous respect for Anders Hejlsberg and his work but Typescript is
not an answer. Typescript is limited in sense that from the beginning it was
doomed to be just a superset of Javascript. And we all know about deficiencies
and "bad parts" of Javascript.

Languages do matter and those with strong functional emphasis are better,
because they enforce you to pursue specific discipline that allows you to
write better code.

Of all functional languages (more or less popular today) in my opinion the
best option is Clojure and Clojurescript. Clojurescript is simply amazing.
It's robust, easy to learn, fast, adaptable, pragmatic, can cover your needs
on all major platforms including iOS and Android. For a long time advocates of
statically typed languages would point to one "weakness" of Clojure - its
dynamically typed nature. But to begin with dynamism of Clojure types always
considered its strength. Besides, Clojure today carries an instrument far more
powerful than static types -
[http://clojure.org/about/spec](http://clojure.org/about/spec). Clojure
community is growing, language is gaining popularity. Because behind seemingly
innocuous, and even arguably (at the first sight) not very appealing lispy
syntax, there is an incredible elegance, power and true astonishment.

------
sbmassey
I was vaguely under the impression that Elm was more an ML style language than
a Haskell style language, so it ought to have modules and functors rather than
typeclassss.

------
phamilton
SYTC is in reference to a comment made pre Elm 0.17, when drastic changes were
made to the language (FRP was dropped, ports were massively simplified, and a
bunch of other stuff).

So he then decides he wants to have the full Elm experience by trying to
replicate a Haskell solution in Elm using a technique that was mentioned in an
issue comment. I feel like in trying to avoid the blub paradox, he ran right
into it.

------
caconym_
It really seems like Elm should implement typeclasses. I don't know Elm, but I
can't really imagine writing serious Haskell programs without them, and I've
seen multiple Elm-related complaints today that were either directly lamenting
their absence or lamenting difficulties that they would have solved,
trivially.

~~~
Skinney
Keep in mind that Evan works at a company that has 55k lines of Elm in
production. Neither Evan, nor the lead-developer of the company, feel that
typeclasses, or something like it, needs to be in the language right now.

~~~
leshow
This is unconvincing to me. Just because Evan and his friends are happy to
write boilerplate and copy-paste the same stuff over and over doesn't mean
it's the right thing to do.

~~~
rtfeldman
Hi! I work at NoRedInk, the aforementioned company with 55,000 lines of Elm in
production.

We don't "copy-paste the same stuff over and over." That would suck. Why would
we be excited about a language that made us do that? Our Elm code is about as
DRY as our JS code was before, except the Elm code is way easier to maintain.

~~~
leshow
How do you compose update functions without writing the boilerplate let ... in
for every Msg? How do you stop your main update function from growing
endlessly as you add new Msgs?

You need only look in the standard library for examples of boilerplate and
not-DRY code. The map function is implemented separately for Lists, Arrays,
etc.

I really want to love Elm. But the more I wrote it the more I realised that
the only answer to those questions is that you solve them with boilerplate and
brute force. When I ask the community what the solution is I'm largely ignored
or told it's not a "real" problem.

~~~
rtfeldman
> How do you compose update functions

If there's shared logic between update functions we extract it into a helper
function. That also makes it easier to test.

I'm not sure how typeclasses would make composing update functions easier, but
in this case we can be concrete. PureScript's Pux library implements the Elm
Architecture, and PureScript has typeclasses. Would you mind showing me some
Pux code that uses typeclasses to improve the situation you're talking about?

~~~
leshow
Extracting to a helper function doesn't change the fact that there is
boilerplate that must be overcome by brute force when composing "components".
Every sub update function needs to be manually wired into the main update
function since the introduction of Html.app. Libraries like elm-return make
this a bit nicer to work with, but because of the restrictions in what Elm
will let you do with it's "magic" there is no alternative.

I don't write PureScript, I can't help you there.

~~~
Skinney
Don't understand how typeclasses would help you here. If you want immutable
single source of truth, which is what Elm provides, you would do the same
thing in Javascript/React and Clojurescript/Om.

I follow the same pattern in a 10k Javascript/React app I'm working on
professionally. I don't see another way of doing things. Not that I'm looking
very hard, cause this really isn't a problem.

------
chillitom
Such aggressive tone, no need, very off putting and unconstructive. If I was
considering employing the author and came across this article I'd be seriously
put off despite the fact he clearly knows a thing or two.

~~~
mfukar
> very off putting and unconstructive

One of those is irrelevant and the other one is false.

There's a lengthy, clear description of a problem, with a use case, leading up
to a feature request...how is all of that "unconstructive"?

In fact, what's definitively unconstructive is the way the feature request is
closed: dismissing the use case as invalid, despite the fact there's a
description of the rationale behind it in the comments.

~~~
chillitom
To clarify, the aggressive tone is non-constructive, as in it detracts from
the article. You're right he makes a constructive point but I bet a bunch of
people don't bother reading that far.

~~~
mfukar
So what if the tone is aggressive? It's a venting piece. It says so in the
second paragraph. Who cares if people bother reading it? Where it mattered -
the actual github request - the tone of the discussion is right on point.

People who ignore the point to come here and complain about the tone, also
further detract from the point.

FWIW, I find it extra hilarious that, in the context of employment search, I
would form an opinion based on how - or what - a person _vents_.

~~~
foldr
How people vent is a very important consideration, when they're likely to vent
at you at some point.

------
anentropic
"my friend and I decided to hackathon our way through an app to help us learn
how to play guitar."

this sounds like a great way to never learn to play guitar

------
OvermindDL1
It seems most of his issues stem from the language and the FFI, not
necessarily the TEA style 'library' (which he claims is 'great' at the start).
There is a Haskell -> JS compiler and an OCaml -> JS compiler, as well as
Bucklescript, which is another OCaml -> JS compiler but actually outputs very
normal looking and readable JS, probably be better to use those.

Consequently I had many of the same complaints, though not quite to the extent
or wording he does, so I made my own TEA-like library on Bucklescript/OCaml
and ported many of the Elm examples to it, most were basic copy/pastes with
the most minor of syntactical differences (`with` instead of `|` and so forth,
basically Elm->OCaml differences), I have it up (with code link) at
[http://overminddl1.com/bucklescript/](http://overminddl1.com/bucklescript/)
if anyone is curious. Not production worthy by any stretch but I do clean it
up and add more and more to it over time, already can do near all that Elm's
libraries can do, in addition to some of the community libraries.

Continuing on the article, he basically re-implemented OCaml's Witness style
(done via OCaml's modules), it was fascinating watching someone build it in
Elm I must admit.

He does focus too much on typeclasses, the witnesses he wrote is the way OCaml
does it (although with a bit less syntax, and much more an upcoming update),
which is not a typeclass form, but something similar.

An aside, where he mentions 'If you don’t want to read the essay, SYTC
essentially says “hey, why don’t we pass around an object that describes the
implementation of the contract that we care about, rather than having the
compiler infer it for us?”. If you’re familiar with Scala, this is how they
implement typeclasses in terms of implicit parameters. If you’re not, SYTC is
equivalent to passing around a vtable whenever you want to invoke code on a
dynamic target.', that is just what OCaml is doing in a soon-coming version
with its implicit modules. Definitely looking forward to that, even if they
are just fluff. They are basically like Scala's implicit parameters but with
type lookup based on module definitions, still explicit, but significantly
reduces the code required to be written.

------
sitkack

      >I have complaints about Elm after using it during a quick hack session.

~~~
the_duke
The post is opinionated and a bit aggresively worded.

But his(/her?) major complaint is valid: lack of type classes, which
completely kills essential composability and generic properties of Haskell.
And the module system doesn't offer MLs features to make up for it
(signatures).

This means that Elm requires boilerplate for things that are elegantly handled
by type classes.

You may also look at Purescript [1], a more complete Haskell inspired language
compiling to Javascript.

Haskell is a complex language. So I'm not necessarily saying that Purescript
is a good choice for the average developer unfamiliar with functional
languages.

Elms 'lack of features' makes it easy to pick up. Especially if you aren't
familiar with FP. But Elm is TOO simple.

[1] [http://www.purescript.org/](http://www.purescript.org/)

~~~
prepor
You can do everything that you can with typeclasses without them. In fact GHC
compiles Haskell into GHC core, where are no typeclasses.

See
[http://okmij.org/ftp/Computation/typeclass.html](http://okmij.org/ftp/Computation/typeclass.html)

~~~
the_duke
Quote from the second paragraph:

> Knowing what TEDIOUS JOB GHC is doing for us helps us appreciate more the
> convenience of type classes.

Thanks for the link though, I think I read it a few years ago.

~~~
hawkice
In truth, it's a balancing act. More than a few Haskell libraries are more
tedious than Elm code (I've written upwards of 8,000 lines of production Elm
but have been doing Haskell for much longer) because they're so intensely
abstract.

Without typeclasses, that simply doesn't happen. I'd say 90% or more of
Haskell typeclass usage is pointless, and maybe half of what remains is simple
to replace with simpler polymorphism or no polymorphism.

For instance, almost everything here:

[https://wiki.haskell.org/Typeclassopedia](https://wiki.haskell.org/Typeclassopedia)

is replaced, in Elm, by just having an explicit module reference, so
Maybe.andThen instead of andThen. No joke, that replaces essentially all of
it, except some stuff that's not used that often.

~~~
mikekchar
You're way more experienced than me in this, but it seems to me that anywhere
you're going to be replacing polymorphism is going to result in more typing.
If you know the module that you want, then it is trivial, but the point of
type classes (IIUC) is to write generic functions that can act on a variety of
types.

To replace the non-trivial cases is going to require pattern matching, it
seems. If your types change, then you are going to have to update things in
multiple places.

But, like you said, it's not the end of the world. In many cases the intent
will probably be _clearer_. Still, I'd rather have type classes than not.

~~~
hawkice
Typeclasses aren't bad, that's for sure. I kinda want something as flexible as
typeclasses and derive generic but no where near that complex. A big part of
me says I could do well with just promising some JavaScript really really
meets a type signature. Ports are great for side effects but I there might be
room for this for pure functions?

------
hkgumbs
If anyone using elm runs into the same dictionary-comparable issue, please
understand that it's a solved problem: [http://package.elm-
lang.org/packages/robertjlooby/elm-generi...](http://package.elm-
lang.org/packages/robertjlooby/elm-generic-dict/latest)

~~~
leshow
The problem is the compiler magic for what is 'comparable' is unavailable.
This doesn't solve that problem. It creates an entirely new data structure
that is mostly a copy paste of the stdlib Dict.

------
charlieflowers
What is the thought process behind him using the term "witness"? I can tell it
is backed by an interesting perspective and I'd like to learn more about that
perspective.

At one point, he said this witness "proved" something ... so is this coming
from "propositions as types"?

~~~
maxiepoo
The use of the term "witness" here comes from constructive logic, where proofs
of propositions have actual computational content. There "witness" means the
same thing as "proof" but is more evocative that the proof is data that can
actually be manipulated.

You might like this article if you're interested to learn more:
[http://jozefg.bitbucket.org/posts/2015-01-09-constructivism....](http://jozefg.bitbucket.org/posts/2015-01-09-constructivism.html)

------
junke
> [119 people] Of whom, we can assume the majority are web-programmers, and,
> by association, that Elm’s is likely the strongest type-system to which they
> have been exposed.

No.

------
ungzd
Does the same criticism apply to OCaml and F#? Anyone who used these languages
for long time, how do you solve lack of higher-kinded types (or OCaml has
them?) and do polymorphism?

~~~
onlydnaq
I don't really agree with the premise that not having type classes is as big
of a problem that the author thinks, but to answer your question OCaml has
functors which are basically higher order modules. A functor in OCaml is a
module defined over abstract types and you instantiate it with concrete types.

A lot of people in the Haskell community have yearned for this as well, and
the latest version of the Haskell compiler will support something similar
called Backpack.

------
wyager
A few months ago, I spent a few evenings trying both Elm and Purescript. Elm
was easier to get started with, but felt much more cramped and difficult to
scale up to large programs. Purescript was more complicated to figure out (I
had to read about F-algebras to understand Halogen's UI query algebras), but
it's _substantially_ more powerful and flexible. It's very similar to Haskell,
with the addition of built-in record types.

------
chriswarbo
In cases where we're "acting on" some value, like a dictionary, surely we
should be able to store the comparison function in the value? I don't know
Elm, but something like the following Haskell:

    
    
        data Dict k v = D (k -> k -> Bool) [(k, v)]
    
        empty :: (k -> k -> Bool) -> Dict k v
        empty f = D f []
    
        -- and so on
    

Of course, this is a naive linear-time implementation; substitute with
whatever alternative you like. If you already have some type-level
"comparable" thingy, you can make an "emptyFromComparable" to pre-populate
with the built-in compare function.

We could do the same for things like Set too.

As far as I can see, the only 'problem' would be operations like `merge`,
where we might have two different functions. The simplest thing would be to
bias in favour of one, e.g. turning `merge d1 d2` into something like
`extendWith d1 d2`.

I'm not saying this can replace typeclasses or modules in general, but in
these sorts of cases we're _already_ passing around a datastructure, so why
bother passing around the required functions separately?

There's probably some irony here, considering the fact that GHC implements
typeclasses using _dictionary passing_!

~~~
danneu
[http://package.elm-lang.org/packages/eeue56/elm-all-
dict/2.0...](http://package.elm-lang.org/packages/eeue56/elm-all-
dict/2.0.0/AllDict) is an example of a Dict where you pass in a custom (key ->
comparable) function when initializing the datastructure.

------
plaguuuuuu
My reaction to this is mainly that typeclasses seems annoying to use in the
first place, and that the alternative seems, if anything, even more annoying.

------
anonymous_iam
I wish Even had chosen a different name for his project. Elm is (was) a
popular text-based e-mail client for Unix/Linux systems. See:
[https://en.wikipedia.org/wiki/Elm_(email_client)](https://en.wikipedia.org/wiki/Elm_\(email_client\))
I still sometimes use it while shelled into a remote system.

------
chenshuiluke
What's a good alternative to Elm?

~~~
srparish
Language wise scala.js[1] with cats[2] or scalaz[3]. The FRP story there is
unfortunately more complicated.

1| [https://www.scala-js.org/](https://www.scala-js.org/) 2|
[http://typelevel.org/cats/](http://typelevel.org/cats/) 3|
[http://scalaz.github.io/scalaz/](http://scalaz.github.io/scalaz/)

~~~
sjrd
You can go with the Diode [1] library for an Elm/Redux- _like_ architecture.
And with that you don't need to all the way down to cats or scalaz (although
you sure always can if you want to).

[1] [https://github.com/ochrons/diode](https://github.com/ochrons/diode)

~~~
kod
Take two average JS programmers. Hand one of them the Elm docs, the other the
Diode docs. What do you expect will happen?

~~~
magic_quotes
Both will continue using typescript/redux/react combo. Scala.js mostly makes
sense if you are already familiar with scala, that's hardly surprising.

------
VyseofArcadia
> Ord a is a witness that type a is well-ordered, which is to say that for any
> two as, one is definitely less than or equal to another.

What the author described here is a linear order, not a well ordering, despite
linking to the correct Wikipedia page.

------
hellofunk
tl;dr static typing adds lots of complexity to everything, just use
Clojurescript instead.

Ok, I'm jesting. And I like static typing. But sometimes it is easy to get
lost in it when you just want to be productive instead.

~~~
iLemming
As I noted in my comment: Clojure and Clojurescript now have a far superior
instrument than static types, it has `Clojure.spec`

------
marlonicus
I'm keen to hear more about the guitar learning helper you guys built! I've
been planning to build a similar thing for a little while now. Care to do a
blog post on what you guys did?

------
crb002
Evan needs an EXT set of libraries for stuff not in core just like Matz did.
My pain point is forms. Make form generation and client side validation easy
and everything else will follow.

------
rsrsrs86
OP should try do build a better framework/language, then.

------
jedimastert
This might seem like a silly question, but what would happen if you tried to
use the same kind of system, but with another language?

~~~
lmm
What do you mean by "system"? The post talks about how other languages solve
the problem, e.g. typeclasses, or emulating them with classes.

------
bbcbasic
Unfortunately this is an opinionated piece with foul language and it is a bit
offensive. Sandy should take into account that Elm is created by one person
pretty much (‎Evan Czaplicki) who created it in his PhD thesis and has been
maintaining it since. So it's someones baby still, and they might be offended.

It is a remarkable for one person to create a language, runtime, repl,
debugger, compiler to another quirky language i.e. JS that is usable to the
point that people are doing professional work in Elm. Also the compiler
produces easy to understand messages.

Evan has made Functional reactive programming more accessible. I don't think I
would have a chance to understand FRP at all without Elm. Elm has inspired
other frameworks in Purescript and the development of ReactJS.

Sure Elm is not perfect. I found that much of the JS ecosystem not viable in
the Elm world, even with FFI due to the purity of the virtual dom. I can't
just go and easily chuck an impure calendar control in my code.

However despite it's drawbacks I feel the article was a bit strong in putting
down Elm, which is sad because I think there are the seeds of some great
future languages and ideas in there.

~~~
mikekchar
Yeah I read this a few weeks ago and was similarly put off. I will give him
one thing: it got me to start thinking about what I wanted in a functional
language that compiles into JS, which ultimately steered me towards
Purescript.

I think fundamentally he's correct, but the point that he is missing is the
intended audience of Elm. He was not it. Elm is _much_ easier to grasp than
Purescript, for instance. There is less complicated syntax and there are less
complicated features. I would would be quite happy to use it in a team that
isn't familiar with FP and who wanted to use it for front end code. In fact,
although I have yet to do a large project with it, I might even lean toward
Elm over JS/CS and React. It just seems a lot more straight forward, with less
options available for hanging yourself.

But, like I said, generally I agree with him wrt a general programming
language. Purescript is a much better fit for that. I thought about trying to
write some Elm code on server side, but it just seems like putting a square
peg in a round hole. Also, having played with it, the code generation in
Purescript seems really, really good. I have no trouble envisioning what it's
going to generate for me, which I like.

~~~
darkseas
Can I ask if you have found any equivalent to the Elm Architecture in
Purescript?

I have looked at Elm, and Purescript and now Bucklescript, but I have not yet
seen, or wired up myself, something like the Elm architecture.

I should probably buckle down and learn the wiring I need myself, but I have
been finding the typing a little tough.

~~~
pka
Yep, there are several.

[0] [https://github.com/paf31/purescript-
thermite](https://github.com/paf31/purescript-thermite)

[1] [https://github.com/alexmingoia/purescript-
pux](https://github.com/alexmingoia/purescript-pux)

[2] [https://github.com/slamdata/purescript-
halogen](https://github.com/slamdata/purescript-halogen)

------
opvasger
Sandy is wrong.

------
shaunrussell
Yeah, well, you know that's just like ahh, your opinion, man.

------
logicallee
Leo Tolstoy on War and Peace:

"I decided to write a detailed story about events surrounding the French
invasion of Russia, and the impact of the Napoleonic era on Tsarist society,
as seen through the eyes of five Russian aristocratic families; since I
haven't used the language before, for kicks I decided to do it in Swahili.
This blog post will summarize why I hate Swahili and why it's totally
unsuitable for writing about Tsarist Russian society - or, I would say,
anything else. Swahili is awful and needs to die."

Seriously, how can people write blog posts like this? You decided to code up a
new project in a totally new language, and are here to tell us why that new
language is awful. Really? _Really?_ It's not like this is uncommon. People
make these blog posts all the time! What's with this?

\-------------------

EDIT: I got downvoted, but look:

>A few weeks ago, on a whim my friend and I decided to hackathon our way
through an app to help us learn how to play guitar. In a stroke of
inspiration, we decided to learn something new, and do the project in the Elm
programming language, about which I had heard many good things.

>Consider this post to be what I wished I knew about Elm before deciding to
write code in it. Since I can’t send this information into the past and save
myself a few weeks of frustration, it’s too late for me, but perhaps you,
gentle reader, can avoid this egregious tarpit of a language where abstraction
goes to die."

It doesn't take "a few weeks" to learn a programming language!!!

~~~
mikekchar
> It doesn't take "a few weeks" to learn a programming language!!!

No, it doesn't. It takes a few hours.

Which, I'm sure sounds flippant, but hear me out. In the 25-30 years I've been
a professional programmer, I've been paid to use many different languages.
FORTH, Fortran, C, C++, Pascal, Protel, C#, Java, Perl, Ruby, Go,
Javascript/Coffeescript, and Python are the ones that come off the top of my
head, but if I were to go through my CV, I'd definitely remember a few more.

Anyone who has programmed in a handful of the above will notice that (with the
exception of FORTH) these languages are practically identical. They all have
slightly different features and slightly different syntax, but once you know
one, you can pick up another one pretty easily. Especially once you know 5 or
6 of them, you practically don't even need to look at the docs. Just glance at
some example code and you are on your way.

Libraries and frameworks take a _lot_ more time than languages. There are lots
of crazy details that you have to remember. Luckily, most of the major
languages of the same type have _very_ similar base libraries. As long as you
stay away from frameworks, you can be productive pretty much immediately.
Learning the details can take a few weeks, but mostly its unimportant.
Frameworks suck. I've been working in Rails on and off for... 4 years???? I'll
never put that damn thing on my CV. I still don't understand how it works.

So, I don't know this author, but he is clearly knowledgeable in Haskell.
Maybe he also knows Ocaml. It would take you about 15 seconds to pick up Elm
from that background. The rest is discovering (and apparently complaining)
about the bits that don't live up to your expectations. He didn't comment on
the state of the libraries (except to complain about the political process for
getting libraries distributed with the official tools).

I'm not going to defend his rant. I didn't enjoy the tone and I think he
completely misses the point of why the language is there. But his technical
complaints are perfectly reasonable.

I didn't vote you down, but I suspect the reason other people did is that you
are a bit too quick to criticise the author's ability to accurately judge the
language. He seems perfectly capable, even if I disagree with his conclusions
and his tone.

~~~
logicallee
So my point was actually about the specifics of picking up a language _to do a
new project_ , and then complaining about it. (Hence my example of writing a
serious book in a language you don't know.)

I think you really go into superlatives here. It's not fair for you to say "15
seconds", for example. 15 seconds is how long you've been reading this
comment.

(I just timed myself, okay maybe 10-13 seconds.)

I also think that "a few hours" is an exaggeration on your part. Let's pick a
language you've never used - take Objective-C which is similar to C# and C,
C++ which you've already listed, and I think you've never programmed in it,
because if you had you would probably have listed it.

Okay, so now make a serious iOS app in Objective-C in "a few hours". As in,
have one by this time tomorrow. See? It's crazy. That's not how it works.

Maybe the weeks and months and decades run together for you, but there is a
huge difference between doing something for a few months or a year, or doing
something for a couple of weeks as our author reports. I don't like his kind
of blog posts, and it is a whole category - there is this whole type of blog
post where you pick something you've never used, use it to do something new,
and then complain about it, all within the space of your first week or two
using it.

It strikes me as kind of ridiculous. Especially with a provocative title like
"Elm is wrong." Literally, it's like Tolstoy writing War and Peace in Swahili,
a language he didn't know, and then writing a blog post "Swahili is wrong" \--
all within the space of two weeks of when he first learned Swahili. I might be
exaggerating slightly, but I think my analogy holds. It's almost farcical.

~~~
pka
You seem to miss the point.

Elm is _particularly_ easy to pick up for people coming from Haskell. Maybe
not in 15 seconds, but 15 minutes is a totally reasonable estimate.

The author can without doubt write a large project in Elm. His complaints were
about missing the conveniences of abstraction Haskell-like languages provide,
and he is more than qualified to talk about it.

Decomposing records into tuples of comparables has probably crossed his mind
:)

~~~
logicallee
>15 minutes is a totally reasonable estimate [coming from Haskell]. The author
can without doubt write a large project in Elm.

Well, all right. In general I would say that is not true even for languages
that are close, but there are exceptions and I suppose I can take your word
for it.

~~~
pka
It's only because Elm is basic Haskell minus a lot of stuff. So basically if
you know Haskell you already know Elm (so you need the 15 minutes to get up to
speed wrt ports and subscriptions or whatever), but at the same time miss the
stuff that has been left out that you take for granted, hence the failed
attempt of the author to get some of that back.

~~~
logicallee
That could have been presented much more clearly in the article.

It would be interesting to compare with the opinion/experience of someone who
didn't know Haskell, well, right? (Though in that case perhaps the learning
curve is too steep, maybe Elm isn't meant for that.)

~~~
elbear
Actually, that's the thing: Elm is designed for people who don't know Haskell.
It's designed for JavaScript developers who are attracted by the "no runtime
exceptions" claim.

If you're coming from Haskell, you'll see Elm as a dumbed down, stripped
version of Haskell, which will trigger in you the feelings it triggered in the
OP.

~~~
logicallee
Thanks. The chances we'll hear the perspective from a javascript dev with no
haskell exp are slim though.

~~~
elbear
Join the Slack elm channel. You'll find them there.

