When the body of a letrec is a function (the function "bar" below),
failure to perform an inverse-eta expansion on it can have some
surprising consequences. Note that we are not using eta reduction for
its common use of delaying a computation; instead the reduction
eliminates a closure whose environment, it turns out, is very
im****tant. Is this a case where the language ought to match our
intuitions better?
(let
([foo (letrec
([bar
(lambda (a)
(set! bar
(lambda (a) 1))
a)])
bar)])
(write (foo 0))
(write (foo 0)))
; writes "00", despite the set!
(let
([foo (letrec
([bar
(lambda (a)
(set! bar
(lambda (a) 1))
a)])
(lambda (a) (bar a)))])
(write (foo 0))
(write (foo 0)))
; writes "01", as expected