SICP Exercise 4.16

首先,我们先定义一下关于unassigned的定义和函数:

;;Representing unassigned constant
(define UNASSIGNED (quote '*unassigned*))

(define (unassigned? val)
  (eq? val '*unassigned*))

1、修改lookup-variable-value,这个比较简单,这里直接贴出代码:

(define (lookup-variable-value var env)
  (define (env-loop env)
    (define (scan vars vals)
      (cond ((null? vars)
             (env-loop (enclosing-environment env)))
            ((eq? var (car vars))
             (car vals))
            (else
             (scan (cdr vars) (cdr vals)))))
    (if (eq? env the-empty-environment)
        (error "Unbound variable" var)
        (let ((frame (first-frame env)))
          (scan (frame-variables frame)
                (frame-values frame)))))
  (let ((val (env-loop env)))
    (if (unassigned? val)
        (error "Unassigned variable" var)
        val)))
2、scan-out-defines的定义如下:

(define (scan-out-defines body)
  " Translate the form:
  ((define u <e1>)
   (define v <e2>)
   <e3>)
  to:
  ((let ((u '*unassigned*)
         (v '*unassigned*))
     (set! u <e1>)
     (set! v <e2>)
     <e3>))"
  (let ((vars '())
        (vals '()))
    (define new-body 
      (map (lambda (exp)
             (if (definition? exp)
                 (begin (set! vars (cons (definition-variable exp) vars))
                        (set! vals (cons UNASSIGNED vals))
                        (list 'set! (definition-variable exp) (definition-value exp)))
                 exp))
           body))
    (list (make-let vars vals new-body))))
这里用到了一个make-let函数,其定义如下:

;(let ((var1 val1) (var2 val2) ...) body)
(define (make-let vars vals body)
  (cons 'let (cons (map list vars vals) body)))
3,我把scan-out-defines安装到make-procedure里面,因为这样的话,这个转换过程只用在定义时转化一次,如果安装在procedure-body的话,我们需要在每次调用这个procedure的时候,都转换一次。

(define (make-procedure parameters body env)
  (list 'procedure parameters (scan-out-defines body) env))




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值