2008/10/28 Mikael Djurfeldt <[EMAIL PROTECTED]>: > 2008/10/28 Mikael Djurfeldt <[EMAIL PROTECTED]>: >> 2008/10/28 Bill Schottstaedt <[EMAIL PROTECTED]>: >>> I believe this shows a bug in letrec: >>> >>> guile> (let ((x 1)) (let ((x 32) (y x)) y)) >>> 1 >>> guile> (let ((x 1)) (letrec ((x 32) (y x)) y)) >>> >>> Backtrace: >>> In standard input: >>> 2: 0* (let* ((x 1)) (letrec ((x 32) (y x)) y)) >>> 2: 1 (letrec ((x 32) (y x)) y) >>> >>> standard input:2:14: In expression (letrec (# #) y): >>> standard input:2:14: Variable used before given a value: x >>> ABORT: (unbound-variable) >> >> Nope. >> >> From R5RS: >> >> "One restriction on `letrec' is very important: it must be possible >> to evaluate each <init> without assigning or referring to the >> value of any <variable>." > > Sorry. I missed the surrounding let. Yes, it is a bug.
Sorry again (should never easily throw out comments when its about letrec :). The binding of x which letrec introduces covers the entire letrec expression. This means that it *is* an error to refer to it in another init. We should be grateful that Guile detects this, because such code will likely behave in an implementation dependent, and not standard conforming, manner. R5RS again: "The <variable>s are bound to fresh locations holding undefined values, the <init>s are evaluated in the resulting environment (in some unspecified order)"