About expected/actual in type errors

295 views
Skip to first unread message

Evan Czaplicki

unread,
Oct 23, 2015, 7:48:09 PM10/23/15
to elm-dev
LIST ONLY

The new 0.16 alpha provides expected/actual info for type errors, but I wanted to share a bit more about why that is not as simple as it sounds. Maybe I'll turn this into a blog post later :)


Context

For a long long time, people said "I want expected/actual in the error message" and it always felt a bit weird to me. Who is expecting what? Which one is actually the one? It just felt kind of like non-sense knowing how type inference actually works. I basically never looked at expected/actual because I found it confusing conceptually.


Formalizing this feeling

As I worked on this improvement in 0.16, I was able to formalize why I thought expected/actual was dumb. Consider the following code:

badIf n =
    if n < 0 then
        "negative"
    else
        n

In a system that always says expected/actual, this can't make any sense. Is the then branch expected? Are they both expected? And actually not what you expected? It's silly.

There are actually a ton of common cases that are like this:
  • cases where not all the branches match
  • ifs with many clauses where not all the branches match
  • elements of a list do not match
  • ...
It's kind of everything besides when you have a function and an argument does not match up.


How it works in 0.16

So in 0.16 the compiler just does the right thing in every case. If conditional branches do not match, it's like this:

Inline image 1

So as part of this design that lets you give very specific contextual hints, you get the expected/actual thing that folks were asking for as well :)

Inline image 1

So try out alpha3 and let me know how it goes. It'd be cool to have some reviews of this feature before the official release :)

Pete Vilter

unread,
Oct 25, 2015, 10:05:09 PM10/25/15
to elm-dev
This is awesome. The messages specific to each case (argument mismatch, then/else mismatch, list item mismatch, etc) are nice enough, but the type diffing really knocks it out of the park. I feel like this is pretty much exactly what I would say to someone to explain a type error message (from a non-Elm-0.16a3 language) if I were leaning over their shoulder.

Max Goldstein

unread,
Oct 25, 2015, 11:22:55 PM10/25/15
to elm-dev
The really cool thing is that if you have an if-else chain, which is the new way of doing multiway if, it will detect which number branch the error occurred. The Hint at the bottom is also slightly different; it say "all branches of an `if`" need to match, not just "these".

What makes this an pleasant surprise is that if-else chains are not a special case of syntax -- they work just fine in 0.15 -- but the error handling treats them as a single multiway if rather than several nested uses of a binary if.

Evan Czaplicki

unread,
Oct 26, 2015, 5:52:06 PM10/26/15
to elm-dev
So for the announcement of 0.16 there a few things to focus on now:
  • The stuff described here
  • Speed + TCO
  • syntax removals
  • incomplete pattern detection
My feeling is that an improved version of what I've written about in this thread is the major story. The incomplete pattern stuff fits into this as well. So maybe about transitioning from "Compiler errors for humans" to something stronger. Maybe it's time for "Compiler as assistant" or "Pair programming with the combined wisdom of 40 years of the best programmers."

I also maybe can work out a joke about "I don't want to sound like a broken record talking about error messages again, but they are so good now that fixing a broken record takes no time at all!" :P

Anyway, point is, what are your thoughts on what to emphasize?

On Sun, Oct 25, 2015 at 8:22 PM, Max Goldstein <maxgol...@gmail.com> wrote:
The really cool thing is that if you have an if-else chain, which is the new way of doing multiway if, it will detect which number branch the error occurred. The Hint at the bottom is also slightly different; it say "all branches of an `if`" need to match, not just "these".

What makes this an pleasant surprise is that if-else chains are not a special case of syntax -- they work just fine in 0.15 -- but the error handling treats them as a single multiway if rather than several nested uses of a binary if.

--
You received this message because you are subscribed to the Google Groups "elm-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-dev+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elm-dev/78a7f0b1-42fe-4957-852f-c9b6e83b7ba6%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Janis Voigtländer

unread,
Oct 26, 2015, 6:03:31 PM10/26/15
to elm...@googlegroups.com

I find “Pair programming with the combined wisdom of 40 years of the best programmers.” slightly over the top. :)

Hacker News might pull you to pieces over that. (Who are those best programmers you are talking about? Are you entitled to make a judgment about who were the best programmers of the last 40 years?)

Also, while the error and warnings stuff is cool, is it really that much ahead of other languages? GHC can warn you about missing and redundant patterns. Lennart Augustsson gave a cool talk last year about using provenance tracking for giving good “expected vs. actual” errors for his in-house Haskell dialect (and applicable to GHC). I know that Haskell/GHC error messages lack in other regards, and that you can claim better quality for Elm error messages. But in the details, emphasizing “we can do expected vs. actual”, or “the compiler now tells us about stuff we did wrong in pattern matching”, you might simply get responses like “So what, Haskell compilers can do this and do do this”. So being overzealous on this could backfire, is all I’m saying.


Evan Czaplicki

unread,
Oct 26, 2015, 6:18:27 PM10/26/15
to elm-dev
Yes, but of folks who read HN, how many of them are Haskell programmers? And of all Haskell programmers, how many would say that the Haskell errors are easier to work with?

For me the intended audience is JS folks, so the goal would be to express the emotions of working with a typed FP language with nice error messages for an audience who never imagined such an experience being fast, nice, etc.

I agree about that specific phrase though. I personally feel that working with OCaml or Haskell or whatever, it's like some wisdom about writing good code is just there. All I have to do is write code and somehow that wisdom manifests itself in my code without me really understanding the key insight. That's kind of the idea I want to express. So yeah, this has existed for many decades, but I don't think anyone has ever made it accessible to everyone. Probably 95% of programmers have not experienced it, and wouldn't believe it if you told them. The phrase can be tweaked to match the actual meaning I was going for :)

Janis Voigtländer

unread,
Oct 26, 2015, 6:26:00 PM10/26/15
to elm...@googlegroups.com

Yes, but of folks who read HN, how many of them are Haskell programmers?

I have no idea, actually. Maybe not so few?

And of all Haskell programmers, how many would say that the Haskell errors are easier to work with?

Well, they might say that Elm is solving an easier problem on that front, because the Haskell type system is more expressive in many ways.

But anyway, I agree with the general spirit you express in your elaboration of this idea. (About bringing this new experience to JS mainstream developers etc.)


Max Goldstein

unread,
Oct 26, 2015, 7:17:13 PM10/26/15
to elm-dev
One of my college profs had a sticker that looked like the colorful starburst you'd put on a product box. It said, "Now Slower With More Bugs!". The great thing about 0.16 is that it's actually going in the good direction: Simpler, Faster, and More Reliable. Simpler: syntax removals, better error messages. Faster: TCO etc. More reliable: incomplete pattern matching, many bugs fixed.

Evan Czaplicki

unread,
Oct 26, 2015, 7:36:30 PM10/26/15
to elm-dev

And of all Haskell programmers, how many would say that the Haskell errors are easier to work with?

Well, they might say that Elm is solving an easier problem on that front, because the Haskell type system is more expressive in many ways.

I've been hearing people say this, but I think it's bullshit. While it is true that there are more kinds of type errors in Haskell, but I don't think has much explanatory power if you know the details of inference, unification, and constraint solving. Here's what happens when I give the original badIf to GHC:

Inline image 1

It's true that the root unification problem is something that does not exist in Elm, but the overall message is pretty terrible to read. I don't think you can explain all of the quality problems away with type classes. In Elm at least, the parts that makes your error messages nice and contextual is almost entirely independent of "unification" where you'd see the actual details of the type system come out. If a system uses HM(X) and a constraint solver, I have a very hard time believing the X makes a massive difference on all the various things that impact quality of the message, even if the content of that message is fancier.

But hey, maybe there are some details I am not aware of!

Brian Slesinsky

unread,
Oct 29, 2015, 1:40:12 AM10/29/15
to elm-dev
Very pleased to hear that error messages will improve again.

It seems to me that seeing expected and actual types in error messages won't obviously be an advance to Java or Go programmers. People have been asking for this since it's relatively common in mainstream languages.

But the reason these languages get expected/actual right is that most type errors in these language aren't detected via type unification. They don't do much type inference.

So, you could say that you get full type inference *and* great error messages, and that's an uncommon combination.

- Brian

Max Goldstein

unread,
Oct 29, 2015, 9:31:19 AM10/29/15
to elm-dev
That's a good point Brian. If I had, in a C-like language,

void myFunction(int foo){ ... }

myFunction(6.28);

It's pretty clear that an int was expected and a float was given.
Reply all
Reply to author
Forward
0 new messages