if和cond之间的区别?

时间:2009-11-24 04:47:52

标签: scheme sicp

我正在学习sicp并做ex2.23 我已经完成了以下代码:

(define (for-each proc items)
   (if (null? items)
       #t
       ((proc (car items))
        (for-each proc (cdr items)))))

但在运行时会导致错误:程序应用程序:预期程序,给出:#;参数是:()

我想我知道原因:我以递归方式调用for-each函数,每次调用for-each想要返回值

但是当我修改了代码时:

(define (for-each proc items)
  (cond ((null? items) #t)
        (else (proc (car items)) (for-each proc (cdr items)))))

运行良好。我不明白,为什么?在 cond 中,是否每次调用for-each都不需要返回值?

我使用DrScheme,并选择语言SICP

我不是母语英语的人,所以如果有一些没有清楚描述的话,请告诉我

1 个答案:

答案 0 :(得分:7)

  

但在运行时会导致错误:程序应用程序:预期>程序,给出:#;参数是:()

     

我想我知道原因:我递归调用for-each函数,>每个被召唤的人都希望返回价值

不,这是因为在if的替代条款中,您有((proc (car items)) (for-each proc (cdr items)))组合。您打算按顺序评估两个组合(proc (car items))(for-each proc (cdr items)),为此,您认为将它们放在另一对括号中会起作用。但实际上,您指定的是(proc (car items))的结果是应用于参数的过程,该参数是(for-each proc (cdr items))的返回值。情况并非如此,您会收到错误消息。关键点在于Lisp中的括号不是用于分组,而是具有明确的意义。

问题是if在该位置只能有一个组合,而你想要连续两个。另一方面,cond不受此限制;你可以按照你的心愿,在cond条款的后续部分放置一系列单独的组合。这种状况只是语言的定义方式。

您也可以在这些情况下使用cond,但如果您仍想使用if,则可以选择将多个组合填充到一个组合中。 E. g。你可以创建一个lambda程序,它的主体是两个组合并立即将其关闭:

(define (for-each proc items)
   (if (null? items)
       #t
       ((lambda ()
          (proc (car items))
          (for-each proc (cdr items)) )) ))

或者您可以使用实际上用于此目的的begin

(define (for-each proc items)
   (if (null? items)
       #t
       (begin
          (proc (car items))
          (for-each proc (cdr items)) ) ))