我正在阅读使用Lisp的方言的SICP。我的问题是,为什么需要下面定义的序列到表达式的转换函数,它在条件定义中使用,而在if表达式中不使用?
(define (sequence->exp seq)
(cond ((null? seq) seq)
((last-exp? seq) (first-exp seq))
(else (make-begin seq))))
(define (make-begin seq) (cons 'begin seq))
以下是if表达式的定义,不需要序列到表达式的转换:
(define (if? exp) (tagged-list? exp 'if))
(define (if-predicate exp) (cadr exp))
(define (if-consequent exp) (caddr exp))
(define (if-alternative exp)
(if (not (null? (cdddr exp)))
(cadddr exp)
'false))
(define (eval-if exp env)
(if (true? (eval (if-predicate exp) env))
(eval (if-consequent exp) env)
(eval (if-alternative exp) env)))
以下是条件的定义,其谓词确实需要将序列转换为表达式。
(define (cond? exp) (tagged-list? exp 'cond))
(define (cond-clauses exp) (cdr exp))
(define (cond-else-clause? clause)
(eq? (cond-predicate clause) 'else))
(define (cond-predicate clause) (car clause))
(define (cond-actions clause) (cdr clause))
(define (cond->if exp) (expand-clauses (cond-clauses exp)))
(define (expand-clauses clauses)
(if (null? clauses)
'false ; no else clause
(let ((first (car clauses))
(rest (cdr clauses)))
(if (cond-else-clause? first)
(if (null? rest)
(sequence->exp (cond-actions first))
(error "ELSE clause isn't last: COND->IF"
clauses))
(make-if (cond-predicate first)
(sequence->exp (cond-actions first))
(expand-clauses rest))))))
if
表达式只能计算一个conequent表达式或一个alternate表达式。但是cond
表达式计算与条件子句相关的表达式的[[sequence。需要sequence->exp
过程将一系列表达式转换为单个表达式。通过以begin
形式包装序列,可以创建一个表达式,该[if
表达式中的后续表达式或替代表达式。
sequence->exp
的目的是为了方便将cond
表达式转换为if
表达式;因此,必须将在cond
分支中找到的任何表达式序列转换为新创建的if
表达式中的单个表达式。