[plt-scheme] interesting DrScheme error message
Prabhakar Ragde wrote:
> I had a student who wrote code that looked something like this
> (simplified to convey the essence):
>
> (define (f x y)
> (+ x y))
>
> (define (g x y)
> (+
> (f x x)
> 10)
> 20)
>
> Running this in Beginning Student (299.400) highlights the "f" in the
> definition of g and gives the error message:
>
> f: name is not defined, not an argument, and not a primitive name
>
> If, on the other hand, I replace the expression (+ (f x x) 10) with (+ 2
> 10), I get the 20 highlighted, and the more reasonable error message:
>
> define: expected only one expression for the function body, but found
> one extra part
>
> Is there a logical explanation for this? From the student's point of
> view, the first error message is quite incomprehensible. Thanks. --PR
It seems like a bug. To enhance error reporting, DrScheme is attempting
to report errors left to right. In this case, it notices that there are
too many expressions in the function body, but before reporting that, it
tries to check whether there are any errors to report in the first
expression. That check has a bug, in that it is only taking local
lexical bindings into account, not top-level bindings, so it erroneously
reports an error if a top-level binding is referenced.
A simple workaround which improves the error message is to comment out
the following three lines, starting at line 280 in
plt/collects/lang/private/teach.ss:
(when will-bind
(local-expand (car exprs) 'expression (cons #'advanced-set!
will-bind)))
Commenting out these lines avoids the test described above and will give
the error message about "found one extra part" in both cases.
The only downside of this fix is that if there was indeed an error in
the first expression, the "extra part" error message will still be
reported first, so error reporting would not be left-to-right in that
case.
I leave the implementation of the original intended behavior as an
exercise for the PLT team. ;oP
Anton