guile-devel
[Top][All Lists]

## Difference letrec & environment binding (again)

 From: Hans Aberg Subject: Difference letrec & environment binding (again) Date: Thu, 4 Aug 2011 10:56:16 +0200

```I try to understand how Guile transforms 'letrec' (returning to the topic of an
earlier post on this list). Define

(define (a) (letrec (
(even? (lambda (n)
(if (zero? n) #t (odd? (- n 1)))))
(odd? (lambda (n)
(if (zero? n) #f (even? (- n 1))))))
(even? 1000)))

(define (b) ((lambda ()
(define even? (lambda (n)
(if (zero? n) #t (odd? (- n 1)))))
(define odd? (lambda (n)
(if (zero? n) #f (even? (- n 1)))))
(even? 1000))))

Then, by
scheme@(guile-user)> ,x a
scheme@(guile-user)> ,x b
letrec is, in this case, merely transformed into the second.

But it can't be true in general. Define

(define (c) (letrec (
(yin
((lambda (cc) (display #\@) cc)
(call-with-current-continuation (lambda (c) c))))
(yang
((lambda (cc) (display #\*) cc)
(call-with-current-continuation (lambda (c) c))))
)
(yin yang)))

(define (d) ((lambda ()
(define yin
((lambda (cc) (display #\@) cc)
(call-with-current-continuation (lambda (c) c))))
(define yang
((lambda (cc) (display #\*) cc)
(call-with-current-continuation (lambda (c) c))))
(yin yang))))

Unless I have missed something, the same transformation, but applied to code
with some non-local call/cc thrown in. Now, (c) and (d) produce different
results, so they can't be semantically the same, which is confirmed by
scheme@(guile-user)> ,x c
scheme@(guile-user)> ,x d

So letrec is transformed to something else. What might that be?

Hans

```