Improved error messages in Wipple
Wipple's new typechecker operates on groups of expressions, enabling more informative error messages.
I have been working on a new compiler architecture for Wipple since May, and it’s starting to compile more complex programs now. One notable change to the compiler is how the typechecker operates on groups of expressions rather than type variables. This allows it to thread specific expressions through generic functions and during instance resolution, resulting in much more informative error messages.
Here’s an example of how the new typechecker can handle interactions between multiple generic functions. This program adds two numbers and passes the result to a function accepting a string:
Add : left right (infer sum) => trait (left right -> sum)
instance (Add Number Number Number) : _
add :: left right -> sum where (Add left right sum)
show :: String -> ()
show (add 1 2)
In the current compiler, you get this “expected/found”-style error message:
show (add 1 2)
^^^^^^^^^
This code is supposed to be a number, but it's actually a string
…while the new compiler highlights all the places that influenced this conflict, including the relevant portions of type annotations!
instance (Add Number Number Number) : _
^^^^^^
add :: left right -> sum where (Add left right sum)
^^^ ^^^
show :: String -> ()
^^^^^^
show (add 1 2)
^^^^^^^^^
`add 1 2` is `String` or `Number`, but it can only be one of these.
Custom error messages are now written using comments rather than inline strings:
-- Missing parentheses around the inputs to `+`.
[error] instance (Add () right sum)
show 1 + 2
show 1 + 2
^^^^^^^^^^
Missing parentheses around the inputs to `+`.
(This feedback comes from the instance `Add () Number _`.)
They can also reference type parameters using Markdown link syntax. Thanks to the new typechecker, these links automatically resolve to the specific expression relevant to the error!
-- Cannot display [`value`] on the screen.
[default] [error] instance (Describe value)
my-value : ()
show my-value
show my-value
^^^^^^^^
Cannot display `my-value` on the screen.
(This feedback comes from the instance `Describe ()`.)
Eventually, I plan to render this information in a visual format rather than with source code annotations. I’m excited to continue this new architecture!