if 和 cond 之间的区别?

发布于 2024-08-12 19:23:32 字数 693 浏览 1 评论 0原文

我现在正在学习 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

我的母语不是英语,所以如果有没有描述清楚的地方,请告诉我

i'm learning sicp now and do the ex2.23
i have wrirten the following code:

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

but when running, cause error: procedure application: expected procedure, given: #; arguments were: ()

i think i know the reason: I call the for-each function recursively, every called for-each wanted to return value

but when i have modified the code:

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

it runs well. I don't understand, why? in cond, does every called for-each no need to return value?

i used DrScheme, and choose language SICP

i'm not a native speaker of english, so if there is sth which isn't described clearly, pls tell me

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

铁轨上的流浪者 2024-08-19 19:23:32

但运行时,出现错误: procedure application: Expected >程序,给定:#;参数是:()

我想我知道原因:我递归地调用 for-each 函数,>每个调用 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 项目))。情况并非如此,并且您会收到错误。关键是Lisp中的括号不是为了分组,而是有一定的意义。

问题是 if 在该位置只能有一个组合,而您希望有两个连续组合。另一方面,cond 则不受这样的限制;您可以根据需要在 cond 子句的后续部分中放置任意长的单个组合序列。这种情况就是语言被定义为如何工作的。

在这些情况下,您也可以使用 cond,但如果您仍然想使用 if,可以使用一些选项将多个组合填充到一个组合中。例如您可以创建一个 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)) ) ))

but when running, cause error: procedure application: expected > procedure, given: #; arguments were: ()

i think i know the reason: I call the for-each function recursively, > every called for-each wanted to return value

No, it is because in the alternative clause of if you have the combination ((proc (car items)) (for-each proc (cdr items))). You intended to evaluate the two combinations (proc (car items)) and (for-each proc (cdr items)) sequentially, and to that end you thought putting them in another pair of parentheses would work. But in actuality, what you have specified is that the result of (proc (car items)) is a procedure to be applied to the argument which is the return value of (for-each proc (cdr items)). This is not the case, and you get an error. The key point being that parentheses in Lisp are not for grouping, but have a definite significance.

The problem is that if can only have a single combination in that position, whereas you want to have two in a row. On the other hand, cond does not suffer such a restriction; you can put as long a sequence of individual combinations in the consequent part of a cond clause as your heart desires. This state of affairs is simply how the language is defined to work.

You can just as well use cond in these situations, but if you still want to use if there are some options for stuffing multiple combinations into one. E. g. you can create a lambda procedure whose body is the two combinations and immediately fire it off:

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

Or you can use begin which is actually meant to be used for such a purpose:

(define (for-each proc items)
   (if (null? items)
       #t
       (begin
          (proc (car items))
          (for-each proc (cdr items)) ) ))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文