Gauche icon indicating copy to clipboard operation
Gauche copied to clipboard

Evaluation order and error messages

Open lassik opened this issue 5 years ago • 8 comments

$ gosh -r 7
gosh[r7rs.user]> (receive (a b) (values 1 2) (list a b))
*** ERROR: unbound variable: b

The real error is that receive macro is not defined in R7RS mode:

gosh[r7rs.user]> receive
*** ERROR: unbound variable: receive

I presume the operands are evaluated right-to-left. Since none of receive, a and b are defined, b is the first to cause an error. It would be more obvious if the first operand was evaluated first, because if it's supposed to be a macro, that macro may be intended to bind the rest of the operands.

lassik avatar Sep 08 '19 12:09 lassik

Another example:

$ gosh -r 7
gosh[r7rs.user]> (use gauche.process)
*** ERROR: unbound variable: gauche.process

lassik avatar Sep 08 '19 12:09 lassik

This has been brought up before. It does perplex users. The thing is that Gauche VM is a stack machine and evaluating the operator last is the optimal (otherwise we need extra stack operation or extra binding check.)

One solution to make it less confusing without sacrificing performance is to make error reporting more smart, e.g. in the first example, let it report like:

*** ERROR: unbound variable: b
   while evaluating (a b)
   while evaluating (receive (a b) ....)

shirok avatar Sep 08 '19 19:09 shirok

This is a bit of a hack, but could you add an extra evaluation in case of error? I.e.:

  1. It would start by evaluating b then a as it does now.
  2. If one of those fails, and the head is a symbol (e.g. receive), and that symbol is not bound, then it shows an error about that.
  3. It the evalutation fails but the head is not an unbound symbol, it shows an error about b.

If b is replaced by some complex expression that succeeds, but a fails, you'd probably have to prove that b does not mutate the head (rebind receive).

lassik avatar Sep 09 '19 07:09 lassik

Maybe it would be enough to have even more obvious wording in the error message:

*** ERROR: unbound variable: b
   evaluating procedure call (a b)
   evaluating procedure call (receive (a b) ....)

lassik avatar Sep 09 '19 07:09 lassik

Since error happens in the code that interpreting VM instruction, and at that time it's not trivial to find which is the "head" of the expression esp. after optimization, I guess it'd be a lot easier for the error handler to find and show relevant debug info than try to evaluate the head of S-expr.

shirok avatar Sep 09 '19 07:09 shirok

Does the VM architecture make it tricky to look up bindings for each stack frame?

lassik avatar Sep 09 '19 08:09 lassik

Yes. The stack frame won't necessarily correspond to the source code scopes. If I reimplement a debugger (I once had one, but it became obsolete after I rewrote VM) I need some debug info that precisely identify which variable is where, but I'll do it in the way that's not hinder performance, so looking up such info would be tricky.

shirok avatar Sep 09 '19 08:09 shirok

I understand. If the evaluating procedure call thing can be done easily, it would already be a big help.

lassik avatar Sep 09 '19 08:09 lassik