乐正

Actions speak louder than words.

Sicp-ex4-8

问题

“命名let”是let的一种变形,具有下面的形式:

1
(let <var> <bindings> <body>)

其中的<bindings><body>与常规的let完全一样,只是在<body>里的<var>应该约束到一个过程,该过程的体就是<body>,而其参数就是<bindings>里的变量。这样,我们就可以通过调用名字为<var>的过程的方式,反复执行这个<body>。举例说,迭代行的斐波那契过程(见1.2.2节)可以用命名let重写为:

1
2
3
4
5
6
7
(define (fib n)
  (let fib-iter ((a 1)
                 (b 0)
                 (count n))
    (if (= count 0)
        b
        (fib-iter (+ a b) a (- count 1)))))

请修改练习4.6中的let->combination,使之能够支持命名let

解答

练习4.8 (ex4-8.scm) download
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
(define (let? exp)
  (tagged-list? exp 'let))

(define (let->combination exp)
  (cond ((list? (cadr exp))
         (make-lambda (let-params exp)
                      (let-body exp)))
        ((symbol? (cadr exp))
         (make-define (let-named-name exp)
                      (let-named-params exp)
                      (let-named-body exp)))
        (else (error "Unknown let -- LET->COMBINATION" exp))))

(define (make-define name params body)
  (list 'define (cons name params) body))

(define (let-named-name exp)
  (cadr exp))

(define (let-named-params exp)
  (map car (caddr exp)))

(define (let-named-body exp)
  (cadddr exp))

(define (let-params exp)
  (map car (cadr exp)))

(define (let-body exp)
  (caddr exp))

draft

« sicp-ex4-7 sicp-ex4-9 »

Comments