Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scheme 如何理解这种延续?_Scheme_The Little Schemer - Fatal编程技术网

Scheme 如何理解这种延续?

Scheme 如何理解这种延续?,scheme,the-little-schemer,Scheme,The Little Schemer,如何编写此延续的执行步骤?使用call/cc运算符使用当前延续调用给定过程(因此名为callwithcurrent continuation)。所以要理解它是如何工作的,我们需要知道当前的延续是什么 在您的程序中,在执行调用/cc时,延续如下所示: (let ([x (call/cc (lambda (k) k))]) (x (lambda (ignore) "hi"))) => "hi" 其中,HOLE是要插入的值的占位符。换句话说,延拓是剩余的计算。如果要继续,可以在延续中

如何编写此延续的执行步骤?

使用
call/cc
运算符使用当前延续调用给定过程(因此名为
callwithcurrent continuation
)。所以要理解它是如何工作的,我们需要知道当前的延续是什么

在您的程序中,在执行
调用/cc
时,延续如下所示:

(let ([x (call/cc (lambda (k) k))])
    (x (lambda (ignore) "hi")))  => "hi"
其中,
HOLE
是要插入的值的占位符。换句话说,延拓是剩余的计算。如果要继续,可以在延续中插入一个值

现在,
call/cc
捕获此延续并将其传递给过程
(lambda(k)k)
。您可以看到,这个过程只是立即返回continuation。因此,该计划简化为:

CONT = (let ([x HOLE])
         (x (lambda (ignore) "hi")))
应用
call/cc
捕获的连续性将当前计算替换为插入您给定值的连续性。因此应用程序
(x(lambda(忽略)“hi”)
变成:

(let ([x CONT])
  (x (lambda (ignore) "hi")))

其余部分应该根据您已经了解的lambda和应用程序进行操作。

在第一行
[x(call/cc(lambda(k)k))]
我们正在创建一个新的延续,它绑定到接收的
lambda
中的
k
参数。返回
k
,然后将其绑定到
x
局部变量-因此,
x
是一个延续

在第二行中,
x
用一个参数
lambda
调用;参数被忽略,调用
(lambda(ignore)“hi”)
的结果是
“hi”
,它最终作为继续操作的结果返回。这相当于简单地调用:

(let ([x (lambda (ignore) "hi")])
  (x (lambda (ignore) "hi")))

为什么这个表达式计算为“hi”

第一步是确定
k
的外观:

(let ([x (call/cc (lambda (k) k))])
  (x (lambda (ignore) "hi")))
我们立即看到,这与

(define k
  (lambda (value)
    (let ((x value))
      (x (lambda (ignore) "hi")))))
但是,我没有提到一个小细节。如果
k
为 一旦被调用,它就好像是在尾部位置被调用一样

(define k
  (lambda (x)
    (x (lambda (ignore) "hi"))))
因此
(f(k3))
对于所有的延续
k
call/cc
构建是 与
(k3)
相同。这总是有点棘手

因此,让我们使用
lambda^
来表示它引入的函数 将被调用,就像它处于尾部位置一样

(define k
  (lambda (x)
    (x (lambda (ignore) "hi"))))
现在我们知道了什么是
k
,我们还需要知道 out of
(call/cc(lambda(k)k))
实际上使用的是默认值

它应该被正确地写为

(define k
  (lambda^ (x)
    (x (lambda (ignore) "hi"))))
在函数的顶部总是隐含着对k的调用 传递给
call/cc
的lambda表达式的主体

我们知道什么是
k

因此,我们知道,这必须与(为了便于阅读,让我们 将参数位置中的
x
转换为
y
。)

因此,我们将这两个位置评估为函数

一旦我们在函数位置调用函数, 我们完成了,因为它是由
lambda^
领导的,所以我们需要知道这一点

((lambda^ (x) (x (lambda (ignore) "hi")))
 (lambda^ (y) (y (lambda (ignore) "hi"))))
计算为,替换为
x

((lambda^ (x) (x (lambda (ignore) "hi")))
 (lambda^ (y) (y (lambda (ignore) "hi"))))
还有一步,用
y

导致

((lambda(忽略)“hi”)(lambda(忽略)“hi”)
,它忽略 它的参数并返回“hi”

((lambda^ (x) (x (lambda (ignore) "hi")))
 (lambda^ (y) (y (lambda (ignore) "hi"))))
((lambda^ (y) (y (lambda (ignore) "hi")))
 (lambda (ignore) "hi"))