Scheme 什么是;“下一步”;这是什么意思?

Scheme 什么是;“下一步”;这是什么意思?,scheme,sicp,Scheme,Sicp,我正在阅读SICP,并使用drracketsicp包作为IDE和解释器。来自SICP的代码: (define (sum func a next b) (if (> a b) 0 (+ (func a) (sum func (next a) next b)))) (define (inc n) (+ n 1)) (define (sum-cubes a b) (sum cube a inc b)) (define (cube a) (*

我正在阅读SICP,并使用drracketsicp包作为IDE和解释器。来自SICP的代码:

(define (sum func a next b)
  (if (> a b)
      0
      (+ (func a)
         (sum func (next a) next b))))
(define (inc n) (+ n 1))

(define (sum-cubes a b)
  (sum cube a inc b))

(define (cube a) (* a a a))

(sum-cubes 1 10)
该函数用于计算从1到10的立方和。但是我不知道下一个b是什么意思,因为我们增加了a而不是b,增量函数由inc表示

因此,我删除了
next b中的
next

然后我得到了一个错误:
定义:下一步中的重复参数标识符

我试图在语法中查找“next”,但什么也没找到

不知何故,我做到了这一点:

(define (sum func a b)
  (if (> a b)
      0
      (+ (func a)
         (sum func (inc a) b))))
(define (inc n) (+ n 1))

(define (sum-cubes a b)
  (sum cube a b))

(define (cube a) (* a a a))

(sum-cubes 1 10)

但这似乎很奇怪<代码> FUNC<代码>被“代码> Cube 取代,所以它就像C++中的一个函数参数?但为什么它不是
(func(inca))
?Scheme怎么会识别出
func(inc a)
,并知道需要用
cube
替换它?

下一步
只是一个碰巧是函数的参数。它传递了值
inc
,因此函数
sum
中的片段
(下一个a)
正在计算
(inca)
。下面的
next b
只是将这些值传递给
sum
的递归调用

添加


递归调用只是增加传递给
a
的值,让
b
保持原样。当
a>b
时,递归停止。在每个级别上,
func
应用于
a
,并添加到正在累积的值中
func
是示例中的函数
cube
。所以它是按预期对多维数据集求和。

下一步
只是一个碰巧是函数的参数。它传递了值
inc
,因此函数
sum
中的片段
(下一个a)
正在计算
(inca)
。下面的
next b
只是将这些值传递给
sum
的递归调用

添加

递归调用只是增加传递给
a
的值,让
b
保持原样。当
a>b
时,递归停止。在每个级别上,
func
应用于
a
,并添加到正在累积的值中
func
是示例中的函数
cube
。因此,它是按预期对立方体求和。

此表单:

(+ab)
是3个变量的组合<代码>+
a
b
是变量,Scheme在应用程序之前以任何顺序对它们进行求值,这将获取过程对象和值

知道用户定义过程中的参数变成变量是非常重要的。它们可以保存任何值,因此
func
next
只是名称。在您看到的代码中,它们正在被应用,例如,它们在运算符位置用括号括起来,这是唯一的提示,表明它们应该是过程。也就是说,除了注释中的文档外:-)

在操作员位置以外的其他位置的过程只是传递的值。例如,在
(sum func(next a)next b)
中很明显
next
是一个过程,它用于生成第二个参数,并作为值传递。它在下一次迭代中被绑定到
next
,这样它也可以在那里使用。实际上,您可以通过使用闭包来避免这种情况:

;;;把数字和。。。B
;;; 使用过程func作为键和
;;; 计算下一个值的步骤
;;; 例子:
;;; (和(λ(v)(*v2));func
;1;a
(λ(v)(+v2));下一步
;;;      10)             ; B
;;; => 50
;;; = (+ 2 6 10 14 18)
(定义(求和函数a和b)
(定义(辅助对象a)
(如果(>AB)
0
(+(函数a)
(助手(下一个a(())))
(a)
比上面更清楚的方法是使用命名的
let
,您还可以引入一个累加器,使尾部递归,但我想您最终会在本书之后了解到这一点

此表单:

(+ab)
是3个变量的组合<代码>+、
a
b
是变量,Scheme在应用程序之前以任何顺序对它们进行求值,这将获取过程对象和值

知道用户定义过程中的参数变成变量是非常重要的。它们可以保存任何值,因此
func
next
只是名称。在您看到的代码中,它们正在被应用,例如,它们在运算符位置用括号括起来,这是唯一的提示,表明它们应该是过程。也就是说,除了注释中的文档外:-)

在操作员位置以外的其他位置的过程只是传递的值。例如,在
(sum func(next a)next b)
中很明显
next
是一个过程,它用于生成第二个参数,并作为值传递。它在下一次迭代中被绑定到
next
,这样它也可以在那里使用。实际上,您可以通过使用闭包来避免这种情况:

;;;把数字和。。。B
;;; 使用过程func作为键和
;;; 计算下一个值的步骤
;;; 例子:
;;; (和(λ(v)(*v2));func
;1;a
(λ(v)(+v2));下一步
;;;      10)             ; B
;;; => 50
;;; = (+ 2 6 10 14 18)
(定义(求和函数a和b)
(定义(辅助对象a)
(如果(>AB)
0
(+(函数a)
(助手(下一个a(())))
(a)

比上面更清楚的方法是使用命名的
let
,您还可以引入一个累加器,使尾部递归,但我想您最终会在本书之后了解到这一点

谢谢!你能看一下编辑过的帖子吗?我一分钟前就知道了,但我还是不明白,AFAIK方案要求所有函数都用括号包装,对吗?那不应该是(苏