Info-Tech

Haskell error messages: reach on

I’m to take into accounta good fan of strongly typed languages, and my popular GC’d language
is Haskell. And I want you, the reader, to retain that in mind this day.
What I’m writing is about a commentary about a language I deeply bask in,
some loving criticism.

So here’s what took space: About a days ago, I became as soon as showing off some Haskell
for a buddy who primarily programs in Python. The stakes have been high
– can even I present that this weird and wonderful language became as soon as worth some
investigation?

My well-known focal point became as soon as on limitless lists, and defining fibonacci as a
recursive details building
– all fun issues to blow their personal horns Haskell’s laziness.
Nonetheless within the future, we wrote an expression accidentally that had a kind
error in it, and so we bought to leer how the compiler treated such issues.
I don’t be conscious the precise expression – it became as soon as deep in context – but
the subject became as soon as I became as soon as seeking to add an integer to an listing. One thing
analogous to 1+[2,3].

Now, in some “weakly typed” languages,
this kind of thing is finally allowed, as
a colleague of mine currently pointed out:

[jim@palatinate:~]$ node
> 1+[2,3]
'12,3'

This is, obviously, hilarious. Nonetheless! We shouldn’t paint “weakly typed”
languages with this kind of vital brush. In my buddy’s native Python, it
would have been an error, as it desires to be. It is miles a jog-time error, but
what does that topic within the occasion you’re working in an interpreted language,
writing ad hoc scripts. The vital thing is that failure is
identified as failure, and it doesn’t strive to
continue with nonsense:

[jim@palatinate:~]$ python3
Python 3.8.10 (default, Nov 26 2021, 20: 14: 08)
[GCC 9.3.0] on linux
Kind "wait on", "copyright", "credit ranking" or "license" for more details.
>>> 1+[2,3]
Traceback (most most up-to-date name last):
  File "", line 1, in 
TypeError: unsupported operand kind(s) for +: 'int' and 'listing'

This is an error message. It’s even a comely decent error message.
There are a good deal of stuff probabilities are you’ll perhaps perhaps additionally bolt to the + operator in Python,
but an int and a listing collectively are no longer amongst them.

So now, what did Haskell assassinate, this language that I’m seeking to blow their personal horns?
Successfully, unfortunately, my buddy didn’t scrutinize the precise subject within the code,
but became as soon as first made conscious about it from the compiler’s error message. And
as soon as you happen to’ve ever performed this before in Haskell, you’re potentially wincing appropriate
now, on legend of you know what this error message is:

[jim@palatinate:~]$ ghci
GHCi, model 8.6.5: http://www.haskell.org/ghc/  :? for wait on
Prelude> 1+[2,3]

:1:1: error:
    • Non kind-variable argument within the constraint: Num [a]
      (Use FlexibleContexts to permit this)
    • When checking the inferred kind
        it :: forall a. (Num a, Num [a]) => [a]

Now, my buddy didn’t understand this error message at all.
Since I became as soon as in Demonstration Mode, my intuition became as soon as to point out off it to him,
but after about a untrue starts, I spotted that this would simply no longer
wait on, and pointed out that you just couldn’t add integers to lists,
and showed him the place this became as soon as going down (it became as soon as a bit more
subtle than this instance).

Nonetheless since then, my colleagues and I have been discussing error messages in
Slack, namely how appropriate Rust’s error messages are, namely
how a lot better they’re than Haskell’s. So I had a possibility to
paste that very irascible Haskell error message me and my buddy stumbled on
into the Slack. There, it served as a case leer, so we can even talk about how
problematically incomprehensible it’s miles, sparking a good deal of debate, from
which I shall strive to extract the most provocative parts into this put up.

For one, this error message has itsy-bitsy to assassinate with the concrete
subject. The subject is – and the error message should always claim this – that
probabilities are you’ll perhaps perhaps additionally’t add lists. Specifically, in Haskell, probabilities are you’ll perhaps perhaps additionally handiest add issues that
put in force the Num typeclass (which lists don’t), and so that you just’d think the
compiler would be wonderful ample to show any place on this error message
one thing along the traces of “looking ahead to [a] to have Num occasion,
but it completely would not.” That’s the precise subject, despite the fact that no longer neatly-explained.

Nonetheless as one more, ghc tries to expend you meant what you wrote, and decide
out a map whereby [a] can have the Num occasion. This is the place
it fails, and then it affords advice on the system to provide that succeed.
As my professor-colleague parts out, that is unsafe advice, seriously
for inexperienced persons, on legend of there’s no map that the usage of FlexibleContexts
will finally wait on in that concern. The subject isn’t that these
lists aren’t numbers in affirm, and that it is advisable to handiest accept
lists that are numbers to your characteristic. The subject is that no lists
are (or no longer no longer up to desires to be) numbers! Nonetheless a newbie can even appropriate note
the advice, strive to determine out what the hell FlexibleContexts are,
and procure themselves in a world of disaster, and no closer to solving the
precise subject.

Fragment of what causes that is the kind of 1 itself. Haskell, not like
Rust, enables literals love 1 to be interpreted in any number kind.
Provided that Haskell (love Rust) has return-kind polymorphism, it’s going to without lengthen
categorical this within the kind machine:

Prelude> :kind 1
1 :: Num p => p

In Rust, this would be one thing love impl Num. It methodology that 1 can
be any kind that’s Num. Mix that with the fact that + requires
its arguments to be Num and to compare ((+) :: Num a => a -> a -> a),
and when we scrutinize 1+[2,3], we’re simply left seeking to determine out how
[2,3] is Num.

If we did not have this polymorphic literal, this conception that the
which methodology of 1 is flexible, we would have viewed a miles more comprehensible
error message. If 1 meant the identical thing as (1::Integer) (or any
arbitrary possibility), we’d have this comely explanation:

Prelude> (1::Integer) + [2,3]

:4: 16: error:
    • Would possibly perhaps perhaps not match expected kind ‘Integer’
                  with precise kind ‘[Integer]’
    • In the 2nd argument of ‘(+)’, namely ‘[2, 3]’
      In the expression: (1 :: Integer) + [2, 3]
      In an equation for ‘it’: it = (1 :: Integer) + [2, 3]

Or despite the fact that we appropriate had non-numbers on either facet, we’d in an identical map
have an even bigger error message:

[jim@palatinate:~]$ ghci
GHCi, model 8.6.5: http://www.haskell.org/ghc/  :? for wait on
Prelude> () + [1,2]

:1:6: error:
    • Would possibly perhaps perhaps not match expected kind ‘()’ with precise kind ‘[Integer]’
    • In the 2nd argument of ‘(+)’, namely ‘[1, 2]’
      In the expression: () + [1, 2]
      In an equation for ‘it’: it = () + [1, 2]
Prelude>

What is my expend-away here? I don’t think the compiler has been sufficiently
tweaked when it involves error messages, or that the Haskell community
cares sufficiently about inexperienced persons. Rust as a community
locations a good deal of vitality into appropriate error messages, in dispute that despite the fact that
Rust also has a trait probabilities are you’ll perhaps perhaps additionally add to arrays to provide + work,
it serene has an even bigger error message:

error[E0277]: cannot add `[{integer}; 2]` to `{integer}`
 --> take a look at.rs:2:7
  |
2 |     1 + [2,3];
  |       ^ no implementation for `{integer} + [{integer}; 2]`
  |
  = wait on: the trait `Add<[{integer}; 2]>` is no longer implemented for `{integer}`

Nonetheless I also think the semantics of 1 are too liberal, leaving the compiler
in an awkward space. Survey, the queer thing is, probabilities are you’ll perhaps perhaps additionally show [2,3]
a bunch, making 1+[2,3] an expression that adds two lists:

occasion Num [a] the place
    (+) = (<>)
    (-) = (<>) -- Eh, why no longer?
    [2,3] = (<>)
    declare = reverse
    abs = identification
    signum = const []
    fromInteger i = expend (fromInteger i) $ repeat undefined

well-known = assassinate
    print $ signum $ 1 + [2,3]

While you’ve outlined lists as a bunch, 1 is without warning a listing if
it desires to be. And this contributes to the concern of finding
the accurate error message: what you requested for is that probabilities are you’ll perhaps perhaps additionally imagine despite every thing.

And within the stop, this leaves me with the feeling that Haskell has
this in overall with Javascript, and that makes me sad. A polymorphic
ample strongly typed language is no longer strongly typed.

Content Protection by DMCA.com

Back to top button