haskell / haskell/error-messages

Type error message overhaul

Open
#541 7 comments 1 reaction 0 assignees View on GitHub
Dominant language
No language data
Stars
76
Forks
19
PR merge metrics
No merged PRs in 30d

Description

I got inspired to write this after watching [this video about teaching Haskell to kids](https://www.youtube.com/watch?v=uTmQ_JtjHgw).

I am now convinced Haskell's error messages could be improved greatly and I have very specific suggestions.

But let's first look at the example error message:

```
Hangman.hs:46:32: error:
* Couldn't match type '[Char]' with 'Char'
Expected type: Char
Actual type: String
* In the first argument of 'makeGuess', namely 'letterInput'
In the first argument of 'gameLoop', namely
'(makeGuess letterInput gs)'
In the expression: gameLoop (makeGuess letterInput gs)
|
46 | else gameLoop (makeGuess letterInput gs)
| ^^^^^^^^^^^
```

The speaker notes these problems:

* You have to know that `[Char]` is a string.
* You have to know that `[Char]` and `String` are the same thing.
* You have to do a lot of squinting to be able to read the last 7 lines.

And it is compared with this roughly equivalent Elm error message:

```
-- TYPE MISMATCH --------------------------------------------------- Hangman.elm

The 1st argument to `makeGuess` is not what I expect:

6| main = Html.text (makeGuess "Five")
^^^^^^
This argument is a string of type:

String

But `makeGuess` needs the 1st argument to be:

Char
```

The speaker encourages GHC contributors to make Haskell's error messages look more like Elm's.

I think it is good to consider this example in a bit more detail and try to extract what exactly it is that makes Elm's message much easier to read and also what things would be harder to change in Haskell due to fundamental differences in language design.

First I'll list a few obstacles:

1. Due to currying we cannot easily know how much arguments the programmer intends his functions to have.
2. Type synonyms (and more advanced things like type families) can obfuscate types in error messages.
3. Specifically, the type synonym `String = [Char]` is confusing, but impossible to change because it would break too much code.
4. Polymorphism causes long distance type conflicts

Here are some general principles I can extract from Elm's approach:

1. Use as little text as possible
2. Use as little formatting (indentation, bullet lists) as possible.
3. Make space
4. Make the subject clear before explaining the details of the problem
5. Write full sentences
6. Write special cases for common patterns
7. Start with the actual code the programmer has written (first actual then expected)
8. Move the file name to the right to make it easy to identify when scrolling through all messages

Some low hanging fruit:

1. Remove the `in the ... of` lines
2. Remove the bullets and indentation
3. Move the location information up
4. Shorten the `filename:line:column: error:` line to just the the type of error and the filename
5. Swap the order of actual and expected
6. Make space

Then we can already get something like this:

```
-- Type mismatch ---------------------------------------------------- Hangman.hs

46 | else gameLoop (makeGuess letterInput gs)
^^^^^^^^^^^
Couldn't match type '[Char]' with 'Char'

Actual type:

String

Expected type:

Char
```

I think this can still be improved further, but this is a good start.

Do you think this is an improvement? Do you agree with my principles for better error messages?

Contributor guide

No contributing guide indexed for this repository

Research direction

No implementation files, tests, or entry points are named. Start by comparing the GHC and Elm examples and reviewing the listed obstacles and principles; done would require an agreed, concrete scope for the error-message changes rather than a general discussion.

Written by the indexing model from the issue text.

Assessment

Tech stack
haskell
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.