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