[racket-dev] [plt] Push #21701: master branch updated

From: Robby Findler (robby at eecs.northwestern.edu)
Date: Fri Dec 10 11:38:36 EST 2010

Both this and Sam's idea seem like good ways to improve the error
message to me. Not sure if Casey or Sam (or Christos?) wants to try to
their hand at the actual formatting or not. I will, if not.

I don't like the "possible fixes include" language, tho-- I prefer
that we either say that this error message is a result of these two
places being wrong and thus fixing one of them will make it go away or
we don't say that.

I lean towards including it because I think that feedback along the
lines of "hey! this error message is wrong because I had to fix a
third place" will help us make the contract system better, but perhaps
Casey's feedback is already enough to make us drop it, I'm not sure.


On Fri, Dec 10, 2010 at 10:22 AM, Eli Barzilay <eli at barzilay.org> wrote:
> Three hours ago, Robby Findler wrote:
>> Okay. So I'll just start by spelling out the pieces of information
>> that's there to be put into a message:
>>  - is the contract blaming the party where the contract was written (or not)
>>  - the source location where the contract was written down
>>  - the contract, written out
>>  - the names of the two parties
>>  - a violation specific message with some details (ususally of the
>>    form "expected an <integer?>, got #f" or similar)
>> The current error message uses that first thing as a conditional and
>> has a different sentence for each of those cases.
> [Warning: see my earlier claim of being inexperienced, so use lots of
> salt.]
> I think that "a sentence" is where the mistake starts -- it works for
> short error messages (that are almost always on one line), but the
> long contract error messages is what makes it annoying to me --
> especially when there's so many bits there, which means that you
> need more verbiage and the result is even less clear (I read it like a
> story to myself, pointing at an imaginary side where my code and
> another side where the other code is...).
> How about this:
>  client contract violation: <viloation message>
>    at:       <name/source of client>
>    contract: <contract>
>    library:  <name/source of library>
>    (contract from: <contract source>)
> and
>  library self-contract violation: <viloation message>
>    library:  <name/source of library>
>    contract: <contract>
>    caller:   <name/source of client>
>    (contract from: <contract source>)
> The words don't matter much, but the idea is:
>  * Show the error message first, that's the most important thing for
>    me, for some cases like "expected an <integer?>, got #f" I'd
>    probably know immediately where the problem is.
>  * Show the faulty code next -- for almost all errors this in
>    combination to the above is all I need to know.
>  * Show the contract next, in more complex cases (like when I
>    confused arguments and have multiple errors, I'll try to decipher
>    this).
>  * Show the library source, just in case there's some problem there
>    (eg, I need to complain or make a feature request, or I'm the
>    library author and I'm trying it).
>  * And finally show the contract location (the least required bit of
>    information for the error).
> In addition, I made the message part appear first assuming that it's
> usually small, and read as text.  The following bits of information
> are all aligned to make them stick out nicely, and I expect that it
> won't take me long before my eyes would learn to quickly jump to the
> relevant information -- this also assumes that each of the bits take
> one line.  The last one is not aligned, but it's aplpicable in cases
> rare enough to not matter.  I don't think that there's any further
> need for explanations (like "the error might be here, or there, or
> there") -- I see where the contract is defined, and in the rare cases
> where none of the lines make sense, I'll get there naturally to find
> out how the bogus contract is defined.
> It's very important (IMO) that the lines are short, for example
>  at: /Users/clklein/tmp/contract-violator.rkt:9.17: (file /Users/clklein/tmp/contract-violator.rkt)
> is bad since it will almost always wrap[*].  I prefer lots of
> shorthands, like "<collects>/foo/bar.rkt" or
> "<home>/tmp/contract-violator.rkt", as well as dropping out obvious
> pieces: in the above case there's no need for the (file ...) part; in
> a library require there's no need for the path.
> [*] (Except for Kevin, who will laugh at the attempt to go beyond a
>    1/4 of his screen's width...)
> [*] (And except for Sam, who is blind to soft line breaks...)
> [*] (Perhaps except for {everyone, except for people who like to use
>    really big fonts}.)
> --
>          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
>                    http://barzilay.org/                   Maze is Life!

Posted on the dev mailing list.