
Putting Down Elm - athaeryn
http://mkndrsn.com/2016/06/06/putting-down-elm/
======
kriro
The title is unfortunate. At first I though...wait why are they discontinuing
Elm, what did I miss.

I've never written anything in Elm but that short post makes me want to try
it. Sounds like a pretty great feature of a language to have easy to follow
error messages you can readily pick up. This also made me chuckle

"""I thought Elm was a pure, functional language, but this is one hell of a
side effect."""

~~~
actsasbuffoon
The error messages in Elm really are outstanding. I've never used a language
that has such clear, concise, and human-friendly error messages. It's a high
water mark, and I hope other programming languages are inspired to try to
equal what Elm has accomplished.

------
vinceguidry
You should always let something else 'drive' your coding. Lots of people like
tests. I personally am not a huge fan of TDD, though it's better than a lot of
alternatives.

Essentially, you set a visible goal. Passing test, compiling program, running
command, visible widget on a browser. Run the test / command / browser URL and
watch it fail. Let the error message you get determine your next step.

It makes a good debugging workflow too. The first step is to get a
reproduction. Then you need to set up an environment where you can repeatedly
and idempotently reproduce the bug at will. Then all you have to do is keep
trying and learning things about the system until you know enough to devise a
fix. Here you can manipulate the command itself to exercise less of the
system, giving you a clearer idea of where the bug is.

Whereas if you're building a new feature, you want to keep the command static
until you see what you want to see.

There's nothing magic about programming languages or paradigms that allows you
to do this more easily. It's just how well you know your system. Some domains
are trickier. You need special tools and expertise to reproduce network
errors, and God help you if your stack isn't memory safe.

------
spuz
This kind of comment about Elm is quite hard to understand without context.
Have you ever used a typed language before? Have you ever used a pure language
before? Is there something special about Elm that gives you this kind of
benefit, or do other languages do the same thing?

~~~
orblivion
Haskell does the same thing.

EDIT: I didn't mean to say that Haskell is as easy, or that the error messages
are as good. I just mean that the error messages can give you a nice reminder
of what you were working on, which I believe was the point of this post.

~~~
skybrian
Haskell had poor error messages last I tried it. Have they improved?

~~~
danpalmer
Haskell has... precise... error messages. As I learn more about it, the errors
are become more useful, and driving my development in a similar way to with
Elm, however with Elm the learning curve is far shallower _and_ the compiler
helps you up it, whereas with Haskell I'm always just googling types to figure
out what the compiler is trying to tell me.

~~~
thinkpad20
Many of the error messages become clearer with experience, but this is mostly
due to developing an intuition for what is actually wrong with your code based
on the error message you see, not due to the helpfulness of the error message.
Often the actual source of the error is in a different place than what is
reported. Consider what happens if you mean to concatenate two strings but
forget to put `++` in there:

    
    
        Prelude> "foo" "bar"
    
        <interactive>:3:1:
            Couldn't match expected type ‘[Char] -> t’
                        with actual type ‘[Char]’
            Relevant bindings include it :: t (bound at <interactive>:3:1)
            The function ‘"foo"’ is applied to one argument,
            but its type ‘[Char]’ has none
            In the expression: "foo" "bar"
            In an equation for ‘it’: it = "foo" "bar"
    

Yikes. Even worse, consider a similar situation with numbers:

    
    
        Prelude> 1 2
    
        <interactive>:2:1:
            Non type-variable argument in the constraint: Num (a -> t)
            (Use FlexibleContexts to permit this)
            When checking that ‘it’ has the inferred type
              it :: forall a t. (Num a, Num (a -> t)) => t
    

Also the parser errors in Haskell are terrible. That the community has so long
put up with "parse error (possibly incorrect indentation or mismatched
brackets)" is a marvel to me, and is one of the most irritating errors to fix
because of the (at least apparent) simplicity of improving it.

~~~
HelloNurse
The first error message is good: it helpfully includes the exact expression
that craps out, and it means, matching intuition about how Haskell should be
compiled, that the expression "foo" "bar" could only make sense if "foo" were
a function from [Char] (i.e. the type of "bar") to some type t, but
unfortunately "foo" is a [Char]: everyone should understand it easily, even if
gratuitously introducing other names (it and its type t) and details about the
compiler making up type equations is highly inelegant.

The second error message, on the other hand, proves that the first one is a
lucky accident.

~~~
MustardTiger
>The second error message, on the other hand, proves that the first one is a
lucky accident.

No, the second error message just shows that there's more options there so the
error message is vague and not very helpful. The first one is not an accident,
it is the standard type mismatch error.

~~~
HelloNurse
My point is that 1 2 should give the same type of error message as "foo"
"bar", because it is the same kind of error (1 isn't a function with one or
more arguments).

The compiler exposes that when numbers are involved it attempts (and fails)
some fancy and unexpected reasoning involving forall, while with plain type
constructors like [Char] it attempts (and fails) straightforward and
intelligible pattern matching.

Figuring out the type of 1 and 2 might be more difficult than figuring out the
type of "foo" and "bar", but the special rules should be hidden: a compiler
that cares about practical usage would provide unified and clear error
messages, possibly listing sets of alternative types it was unable to choose
from.

~~~
MustardTiger
>My point is that 1 2 should give the same type of error message as "foo"
"bar", because it is the same kind of error

And my point is that no it should not. "1 2" is more ambiguous, it could be
more things, hence there is a more ambiguous error message.

------
tacos
This is the perfect example of the content-free HN posts that are topping the
charts lately. It contains not a single example of a "helpful error message."
Nor a single line of code from the language in question. Just a 173 word free-
verse poem with some feel-good handwaving.

If this were a post about soap (the salt, not the protocol) we'd downvote the
post as obvious content-free shilling. But because it's some obscure language
that doesn't even make the top 100 TIOBE language list, here we are, upvoting
someone we've never heard of, celebrating his opinion of awesome compiler
error messages that none of us has ever seen, for a language that nobody uses.

[http://www.tiobe.com/tiobe_index](http://www.tiobe.com/tiobe_index)

~~~
pka
In the time it took you to write your content-free comment, you could've
googled Elm and seen the error messages yourself.

~~~
mdm_
Great, I look forward to future HN posts such as "Elm is really super. The
rest of this article is left as an exercise for the reader."

------
programLyrique
This blog post seems to be more explanatory about the error messages of Elm:
[http://elm-lang.org/blog/compiler-errors-for-humans](http://elm-
lang.org/blog/compiler-errors-for-humans)

------
gjolund
Elm has the best error messages of any language I have ever used.

I have dreams about it one day replacing JS as the front end language of
choice.

------
shrugger
What does this mean? There is almost no detail in this other than "Wow Elm is
great and the compiler gives persistent, detailed messages"

which I think most people interested in Elm already knew.

~~~
Tehnix
I guess the only new addition is that a side-effect of the very helpful errors
is that it's easy to eventually come back to your work later on.

There's also a lot less state to keep in your head, as it's usually a lot more
transparent.

------
kemiller
This has always been my experience with TDD, at least if you always leave
yourself a failing test when you go. A lot more labor-intensive, since you are
essentially writing the "compiler" as you go, but a similar effect.

~~~
tlrobinson
I think "gradual typing" like Flow might be a nice middle-ground.

You're still free to quickly sketch out ideas without worrying about type
checking, but you can solidify things by just adding /* @flow */ to the top of
a file and fixing the errors.

I haven't actually tried Elm though, so maybe a "middle-ground" isn't
necessary.

~~~
pka
This will sound counterintuitive to dynamic language people, but prototyping
is actually much easier with types. I often find myself rewriting 50 to 75% of
the codebase in the early stages of prototyping, and without types I'd be much
less willing to do that, settling for a less than ideal design. This design
will then be the base of a potentially large project, which amplifies early
mistakes even more.

~~~
montibbalt
For me types make prototyping WAY faster, especially if "throw" or some other
keyword satisfies the return type of a function. I can write out the function
signatures and data types I need and get things to line up with the help of a
tool that tells me exactly what I need to do (the compiler). This lets me
quickly find a solution without having to actually implement any of it, and
then I have a skeleton ready to fill in with details.

~~~
naasking
> For me types make prototyping WAY faster

Agreed. I can prototype an idea almost entirely in types, and if the types
make sense, then the implementation often follows naturally.

------
therealmarv
ok nice. We know that. I'm personally touching Elm only after they have
something like ComponentDidMount from React or something which is better
implementend than "wait 50msec and do something like set focus" on their
(virtual) DOM rendering is solved: [https://github.com/evancz/elm-
todomvc/blob/8be8914582870d599...](https://github.com/evancz/elm-
todomvc/blob/8be8914582870d59989ce518e6c7d38f8081faaf/index.html#L18-L25)

~~~
kylecordes
I'm not sure this is a fair criticism. The nice thing about this tiny chunk of
code is that there is only one aspect of this example program that needs to
manipulate the already instantiated DOM, and that tiny chunk is explicitly
brought up to the top level and separated and connected back to the program
via the port mechanism. It would certainly be worse if this magic happen
behind the scenes.

Of course it could be better, and that's probably what you are getting at.
Ideally the machinery provided for building web applications would be more
aware of the nature of web applications and have something in the box (still
explicit and obvious, but in the box) to do something like setting focus.

~~~
Hupriene
It's absolutely a fair criticism. The real DOM is stateful, elm's virtual DOM
is not, and elm doesn't provide any tools to manipulate the state of the real
DOM. This impedance mismatch is bound to cause problems any time you are
dealing with the stateful aspects of the DOM. And solutions like the one
linked to by GP are error prone and fragile.

------
hawkice
To me, the most promising thing about elm is how much improvement it has seen.
The last minor version was a huge leap forward for building real things AND
for beginners. The makers of elm (seems to mostly be Evan Czaplicki) think
about things the same way I do, except they are thinking about it more than I
do and more carefully. Whether it's elm or anything else, I'm glad the tool-
explosion has let more people use tools they vibe with. Hopefully it will help
more random people (like me) do more cool stuff.

------
Kip9000
Elm is a great language for web. It's evolving but there are some bits that
need some rework/improvement/rethought like the canvas performance and
managing random number generation. This is difficult with purely functional
architecture. But there are a quite a lot of good thought gone into making the
whole functional programming user friendly and a pleasant experience. Kudos to
the creators/maintainers

------
md224
I feel like something clicked for me once I realized that all functions in Elm
are curried by default. Cool feature.

------
mrcactu5
in my experience, when I am stuck figuring out types, I just let the compiler
do it. As the error messages are so well-formed, it tells me exactly which
lines are inconsistent and how to put the types back together.

most compilers tell you there's a problem but none outline how to fix it the
way Elm does

------
andrewvijay
Fell into the bait! Clicked and disappointed at a different content than
expected

