Subject: bug#14164: letrec: detect illegal accesses to vars before entering body

From: Mark H Weaver <[email-masked]>
Date: Tue, 09 Apr 2013 12:44:07 -0400

Nikita Karetnikov <[email-masked]> writes:

>>> According to the manual [1], this snippet:
>>>
>>> (letrec ((a 42)
>>>          (b (+ a 10)))
>>>   (* a b))
>>>
>>> should return "Error: unbound variable: a."
>
>> The manual doesn't say anything nearly that specific.
>
> Either you missed it or I misunderstood this sentence.  So if you missed
> it, it can be found below 'syntax: letrec* bindings body'.

Oops!  You're right, of course.  Apologies for saying you were wrong.
I'll fix the manual.

>> In general, if the manual says you "may not" do something, or if the
>> R5RS says "it is an error", that means that if you do, the results are
>> unspecified.
>
> Are you talking about the result of 'letrec' or 'b'?  Anyway, why does
> it return 2184 if the results are unspecified?  Could you elaborate?

Well, first of all, I misspoke.  In this case, I should have said (as
the R5RS did) that "it is an error", which in Scheme-standard-speak
means "anything at all could happen".  This is different from "an error
is signaled" or "an error is raised" or "an exception is thrown" which
consitutes a promise to report an error.

When the standard (or the manual) says "the result is unspecified", that
means that some value will be returned, but that value could be
anything.

Although Guile includes a distinguished value shown as "*unspecified*",
which is often used in these cases, it is not always used.  In practice,
we use it when we can easily do so without imposing a runtime cost, as a
debugging aid.  However, it is not always used.

     Thanks,
       Mark