不了解SICP中的计划程序

use*_*279 5 syntax scheme sicp

我正在通过SICP第1章"1.3用高阶程序制定抽象"

我(当前)遇到问题的部分是将程序模板(如下所示)转换为实际程序(如下所示),将其"槽"变为形式参数.我没有得到的是他们在变换过程结束时(在结束括号之前)得到下一个b的地方?

当然它只是模板中的b

无论如何,这是模板......

(define (<name> a b)
  (if (> a b)
      0
      (+ (<term> a)
         (<name> (<next> a) b))))
Run Code Online (Sandbox Code Playgroud)

这是填充参数槽后的过程

(define (sum term a next b)
  (if (> a b)
      0
      (+ (term a)
         (sum term (next a) next b))))
Run Code Online (Sandbox Code Playgroud)

任何照明都非常赞赏

Ósc*_*pez 6

这里理解的关键见解是,在Scheme中,我们可以像传递数字一样轻松地将函数作为参数传递给另一个函数.请注意,模板不完整,应该是:

(define (<name> <term> a <next> b)
  (if (> a b)
      0
      (+ (<term> a)
         (<name> <term> (<next> a) <next> b))))
Run Code Online (Sandbox Code Playgroud)

从模板到实际过程的转换很简单:

  • <name> 是过程名称的占位符,恰好是 sum
  • <term>是在系列中的每个术语上应用的过程的占位符,在实际过程中它也被调用,term但它可以有任何其他名称 - 例如,identity将是一个有用的过程传递
  • <next>是计算系列中下一个元素的过程的占位符,例如它可以像传递一样简单add1,但作者选择也称之为next

next b在实际过程结束部分只是提供next(一个函数)和b(一个号码)参数,函数的递归调用,这是什么在最后一行获得通过:

    (sum            term             (next a)     next             b)
     ^              ^                ^            ^                ^
     function call  "term" function  next number  "next" function  upper limit
Run Code Online (Sandbox Code Playgroud)

还要注意,(next a)实际上是应用next程序的a参数,并沿着传递给递归该应用程序的结果-事实上,这是调用之间改变的值,当它的有效推进递归直到点(> a b)为假.这与我们传递的倒数第二个参数中发生的情况不同next,函数本身而不是应用它的结果.作为一个例子,这里是你如何调用sum过程来添加1和之间的所有数字10:

(sum identity 1 add1 10) ; <term> is `identity` and <next> is `add1`
=> 55
Run Code Online (Sandbox Code Playgroud)

  • "......(下一个)实际上正在应用下一个程序....这与......接下来的传递不同,功能本身......"欢呼老兄.你是个王子 (2认同)