Exercise 4.23. Alyssa P. Hacker doesn’t understand why analyze-sequence needs to be so complicated. All the other analysis procedures are straightforward transformations of the corresponding evaluation procedures (or eval clauses) in section 4.1.1. She expected analyze-sequence to look like this:
(define (analyze-sequence exps)
(define (execute-sequence procs env)
(cond ((null? (cdr procs)) ((car procs) env))
(else ((car procs) env)
(execute-sequence (cdr procs) env))))
(let ((procs (map analyze exps)))
(if (null? procs)
(error "Empty sequence -- ANALYZE"))
(lambda (env) (execute-sequence procs env))))
Eva Lu Ator explains to Alyssa that the version in the text does more of the work of evaluating a sequence at analysis time. Alyssa’s sequence-execution procedure, rather than having the calls to the individual execution procedures built in, loops through the procedures in order to call them: In effect, although the individual expressions in the sequence have been analyzed, the sequence itself has not been.
Compare the two versions of analyze-sequence. For example, consider the common case (typical of procedure bodies) where the sequence has just one expression. What work will the execution procedure produced by Alyssa’s program do? What about the execution procedure produced by the program in the text above? How do the two versions compare for a sequence with two expressions?
首先我们看看原来的 analyze-sequence 都做了些什么:
假设我们有
(begin
seq1
seq2
seq3
seq4)
这样的语句。由原来的 analyze-sequence 产生的结果应该是
(lambda (env)
((lambda (env)
((lambda (env)
(seq1-proc env)
(seq2-proc env)) env)
(seq3-proc env)) env)
(seq4-proc env))
这里的 seq1-proc,seq2-proc …… 是由 (analyze seq1),(analyze seq2) ……产生的 (lambda (env) ..) 表达式。具体形式可以参见 4.1.7 将语法分析与执行分离 。
根据上面分析的结果,整个 sequence 也是 analyze 过的。
但如果把 analyze-sequence 改为了
(define (analyze-sequence exps)
(define (execute-sequence procs env)
(cond ((null? (cdr procs)) ((car procs) env))
(else ((car procs) env)
(execute-sequence (cdr procs) env))))
(let ((procs (map analyze exps)))
(if (null? procs)
(error "Empty sequence -- ANALYZE"))
(lambda (env) (execute-sequence procs env))))
那么,我们可以知道最后的 analyze-sequence 产生的结果是:
(lambda (env)
(execute-sequence '(seq1-proc seq2-proc seq3-proc seq4-proc) env))
也即单个语句已经被分析过了,但最后的整体并没有。(被分析过最终都是返回 (lambda (env) ..))。