繁体   English   中英

延续与功能的区别是什么?

[英]What distinguishes a continuation from a function?

延续描述接下来会发生什么价值,对吧? 这不仅仅是一个获取值并进行一些计算的函数吗?

(+ (* 2 3) 5)

(* 2 3)的延续是(+ _ 5)

(define k (lambda (v) (+ v 5)))

在这里使用call/cc而不使用函数k什么意义?

真正。 所有程序都有延续,直到它停止。 一个延续通常是底层实现计算的一个步骤。

你的例子:

(+ (* 2 3) 5)

组合+取决于组合*首先完成。 因此(+ result 5)确实是(* 2 3)的延续。 但是,这不是这种情况下的程序。 call/cc的用处是当你有一个遗憾而后悔并且想要做其他事情或者你想在以后再回到这个时候。 让我们做第一个:

(define g 0)
(call/cc 
  (lambda (exit)
    (/ 10 (if (= g 0) (exit +Inf.0) g))))

显然,有一个除法是if的结果完成时的延续,但是由于exit运行,整个东西被短路返回+ Inf.0。

你怎么会用一个程序来做到这一点而不让它在之后进行划分? 在这种风格,你不能。

由于Scheme将您的代码转换为Continuation Passing Style(= CPS)并且在CPS call / cc中没有特殊之处,因此这并不是真正的魔力。 在CPS中编写代码并非易事。

这是call/cc的CPS定义

(define (kcall/cc k consumer)
  (consumer k (lambda (ignore v) (k v))))

恭喜! 你刚刚发明了延续传递风格! 你所做的和call/cc之间的唯一区别是call/cc会自动执行,并且不需要你重构你的代码。

“延续”是计算的整个未来。 计算中的每个点都有一个延续,在幼稚的条件下,你可以将其视为当前的程序计数器和当前堆栈。 Scheme call/cc函数可以方便地捕获当前配置并将其打包成一个函数。 当您调用该函数时,您将恢复到计算中的那一点。 因此,延续与函数非常不同(但是延续函数是一个函数)。

有两种常见情况,其中通常会看到应用的call/cc

  1. 非本地出口。 你建立一个延续,做一些计算,突然结束你调用延续的计算。

  2. 重新启动/重新输入计算。 在这种情况下,您可以保存延续,然后根据需要再次调用它。

以下是案例#1的示例:

(begin
  ;; do stuff
  (call/cc (lambda (k)
              ;; do more

             ;; oops, must 'abort'
             (k 'ignore)))
  ;; continue on
  )

以下是案例#2的示例:

> (define c #f)
> (let ((x 10))
   (display (list (+ 1 (call/cc (lambda (k) (set! c k) x))) 111))
   (display " more"))
(11 111) more
> (c 20)
(21 111) more
> (c 90)
(91 111) more

对于这种情况,#2值得注意的是,延续会将您带回到顶级的read-eval-print循环 - 这使您有机会重新调用此示例中的延续!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM