我正在学习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
我不是母语英语的人,所以如果有一些没有清楚描述的话,请告诉我
答案 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)) ) ))