SICP Exercise 4.7
a)为什么let*表达式可以重写为一些嵌套的let表达式?
因为嵌套的let表达式可以让已经做了的约束都是可见的。例如:
(let* ((x 3) (y (+ x 2)) (z (+ x y 5))) (* x z))
可以重写为:
(let ((x 3)) (let ((y (+ x 2))) (let ((z (+ x y 5))) (* x z))))
b)下面我们参考该例子,写出把let*表达式转化为let表达式的实现:
(define (let*->nested-lets exp) (define (expand-clauses bindings body) (if (null? bindings) body (make-let (list (car bindings)) (expand-clauses (cdr bindings) body)))) (expand-clauses (cadr exp) (caddr exp))) (define (eval-let* exp env) (eval (let*->nested-lets exp) env))
c)可以向eval中添加
(eval (let*->nested-lets exp) env)
但是我更喜欢以数据导向的方式,所以只需再增加一条语句:
(put 'let* eval-let*)
测试结果:
;;; M-Eval input: (let* ((x 3) (y (+ x 1))) (+ x y)) ;;; M-Eval value: 7