标签:sicp lambda lisp eval procedure
Exercise 4.8. “Named let” is a variant of let that has the form
(let <var> <bindings> <body>)
The and are just as in ordinary let, except that is bound within to a procedure whose body is and whose parameters are the variables in the . Thus, one can repeatedly execute the by invoking the procedure named . For example, the iterative Fibonacci procedure (section 1.2.2) can be rewritten using named let as follows:
(define (fib n)
(let fib-iter ((a 1)
(b 0)
(count n))
(if (= count 0)
b
(fib-iter (+ a b) a (- count 1)))))
Modify let->combination of exercise 4.6 to also support named let.
希望大家还是有事没事看看原文啦,我才发现见过很多次的modify原来是修改的意思。
关于named let的一些比较什么的,大家可以看这里:【Scheme归纳】3 比较do, let, loop。
从题目的代码中我们也可以看到named-let的名字可以用cadr来取出,也就是书中的fib-iter。而body部分从以下代码中也可以看出来得用3个cdr和1个car。
(let <var> <bindings> <body>)
而parameter题中已经说了是binding中变量,取出binding用caddr,而取出题目示例中的a、b和count等则用map和car即可。取出题目示例中的1、0和n则用map和cadr。
那么接下来我们还需要将named-let转换成函数,用list来构造这些就好,首先当然是’define,然后再用cons把name和parameter构造在一起,最后就是body啦。
当然了,在let->combination中我们需要判断是不是named-let?,那么怎么判断呢,先判断是否是let?,再判断expr的名字是不是符号(symbol?)。
最后就可以写let-combination啦。首先用写好的named-let?谓词来进行判断expr,然后为真的话就调用第257页的sequence->exp函数,否则就用cons来继续构造了。
(define (named-let-name expr)
(cadr expr))
(define (named-let-body expr)
(cadddr expr))
(define (named-let-parameters expr)
(map car (caddr expr)))
(define (named-let-exp expr)
(map cadr (caddr expr)))
(define (named-let? expr)
(and (let? expr) (symbol? (cadr expr))))
(define (named-let->func expr)
(list ‘define
(cons (named-let-name epxr)
(named-let-parameters expr))
(named-let-body expr)))
(define (let->combination expr)
(if (named-let? expr)
(sequence->exp
(list (named-let->func expr)
(cons (named-let-name expr)
(named-let-exp expr))))
(cons (make-lambda (let-vars expr)
(list (let-body expr)))
(let-exp expr))))
标签:sicp lambda lisp eval procedure
原文地址:http://blog.csdn.net/nomasp/article/details/44802781