Chapter 4, Metalinguistic Abstraction
Exercise 4.8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
(define (let? exp) (tagged-list? exp 'let))
(define (let-has-name? exp) (symbol? (cadr exp)))
(define (let-name exp) (cadr exp))
(define (let-vardefs exp)
(if (let-has-name? exp)
(caddr exp)
(cadr exp)))
(define (let-body exp)
(if (let-has-name? exp)
(cdddr exp)
(cddr exp)))
(define (let->combination exp)
(let ((res (fold-right
(lambda (new rem)
(cons (cons (car new) (car rem))
(cons (cadr new) (cdr rem))))
(cons '() '())
(let-vardefs exp))))
(let ((vars (car res))
(vexps (cdr res)))
(define proc (make-lambda vars (let-body exp)))
(if (let-has-name? exp)
;;create a lambda with no arguments and two statements:
;;(i) containing definition of the let-lambda
;;(ii) invocation of the procedure with those arguments.
;;finally create application for this no argument lambda.
(cons
(make-lambda '()
(list (list 'define (let-name exp) proc)
(cons (let-name exp) vexps)
))
'())
(cons proc vexps)
))))
Output:
Note: It should report error if this variable(procedure name) is accessed outside let.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
;; First testing normal/old let
;;; M-Eval input:
(let ((x (+ 1 2)) (y 100)) (+ x y))
;;; M-Eval value:
103
;;; M-Eval input:
(define (fib n)
(let fib-iter ((a 1)
(b 0)
(count n))
(if (= count 0)
b
(fib-iter (+ a b) a (- count 1)))))
;;; M-Eval value:
ok
;;; M-Eval input:
(fib 10)
;;; M-Eval value:
55
;;; M-Eval input:
(define (fib n)
(let fib-iter ((a 1)
(b 0)
(count n))
(if (= count 0)
b
(fib-iter (+ a b) a (- count 1)))) (fib-iter 1 0 1))
;;; M-Eval value:
ok
;;; M-Eval input:
(fib 10)
;Unbound variable fib-iter