19 (letrec ...) is transformed into:
21 (let ((even? '*unassigned*)
23 (set! even? (lambda (n)
27 (set! odd? (lambda (n)
35 letrec is of the form:
37 (letrec ((<var1> <exp1>) ... (<varn> <expn>))
41 (define (tagged-list? expr tag)
42 (or (pair? expr) (eq? (car expr) tag)))
44 (define (letrec? expr)
45 (tagged-list? expr 'letrec))
47 (define (letrec-variables expr)
48 (let ((p (car (cdr expr))))
51 (define (letrec-values expr)
52 (let ((p (car (cdr expr))))
55 (define (letrec->let expr)
56 (if (not (letrec? expr))
57 (error "not a letrec expression -- LETREC")
58 (let ((vars (letrec-variables expr))
59 (vals (letrec-values expr))
60 (body (cdr (cdr expr))))
62 (cons (map (lambda (var)
63 (list var ''*unassigned*))
65 (append (map (lambda (var val)
73 b. In the case where we use lecrec, this gets transformed into let. So, when we call (f 5)
74 a new frame is formed with even? and odd? assigned to '*unassigned. Then these are set to
75 the lambda expressions belonging to even? and odd?.
77 When we use a let in the place of letrec, a frame gets created with even? and odd? assigned
78 to the lambda expressions. Then the body of the let expression (i.e. <rest of body of f>)
79 is wrapped in a lambda which takes as parameters, even? and odd? is called with the lambda
80 expressions corresponding to even? and odd?.
84 (lambda (n) (...reference to o?..))
85 (lambda (n) (.reference to e?... )))
87 So, a frame gets created which assigns e? and o? to the corresponding lambdas. The enclosing
88 environment for it, does not have e? or o? defined. So, these definitions
89 When we draw the environment, the two lambdas passed as parameters do not see each other as their
90 environment is the enclosing env of t. so they are undefined. When the body is evaluated, then
91 these will generate error for undefined references.