]> git.rkrishnan.org Git - sicp.git/blob - src/sicp/ex4_7.rkt
Merge branch 'master' of github.com:vu3rdd/sicp
[sicp.git] / src / sicp / ex4_7.rkt
1 #lang racket
2
3 (provide let*? let*->nested-lets)
4
5 (define (tagged-list? exp tag)
6   (if (pair? exp)
7       (eq? (car exp) tag)
8       #f))
9
10 (define (make-lambda params body)
11   (cons 'lambda (cons params body)))
12
13 (define (let*? expr)
14   (tagged-list? expr 'let*))
15
16 (define (let*-bindings expr) (cadr expr))
17 (define (let*-body expr) (cddr expr))
18
19
20 (define (let*->let bindings body)
21   (cond [(empty? bindings) '()]
22         [else 
23          (let ([binding (car bindings)]
24                [rest-bindings (cdr bindings)])
25            (if (empty? rest-bindings)
26                (cons 'let (cons (list binding) body))
27                (cons 'let (cons (list binding) (list (let*->let rest-bindings body))))))]))
28
29 #|
30
31 (define (make-let bindings body)
32   (cons 'let (cons bindings body)))
33
34 (define (let*->let bindings body)
35   (cond [(empty? bindings) body]
36         [else
37          (make-let (list (car bindings))
38                    (list (let*->let (cdr bindings) body))]))
39 |#
40
41 (define (let*->nested-lets exp)
42   (let ([bindings (let*-bindings exp)]
43         [body     (let*-body exp)])
44     (let*->let bindings body)))
45
46 ;; b
47 #|
48
49 It is enough to add an action for let* expression in eval, as eval
50 gets recursively called for the transformed expressions (assuming that
51 eval has case handlers for let expression whose action is to transform 
52 into lambda expression application and eval it).
53
54 if we add the following action for let* expressions in eval:
55
56 (eval (let*->nested-lets exp) env)
57  =>
58 (eval (let-expression) env)
59 =>
60 (eval (let->combination exp) env)
61 =>
62 (eval (application exp parameters) env)
63
64
65 |#