简体   繁体   English

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

[英]What distinguishes a continuation from a function?

Continuation describes what happens next with some value, right? 延续描述接下来会发生什么价值,对吧? Isn't that just a function that takes a value and does some computation? 这不仅仅是一个获取值并进行一些计算的函数吗?

(+ (* 2 3) 5)

the continuation of (* 2 3) is (+ _ 5) (* 2 3)的延续是(+ _ 5)

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

What is the point of using call/cc in here and not using the function k ? 在这里使用call/cc而不使用函数k什么意义?

True. 真正。 All programs have continuations until it halts. 所有程序都有延续,直到它停止。 One continuation is usually one step in the calculation done by the underlying implementation. 一个延续通常是底层实现计算的一个步骤。

Your example: 你的例子:

(+ (* 2 3) 5)

The combination + is dependent on the combination * to finish first. 组合+取决于组合*首先完成。 Thus (+ result 5) is indeed the continuation of (* 2 3) . 因此(+ result 5)确实是(* 2 3)的延续。 It's not a procedure in this context though. 但是,这不是这种情况下的程序。 The usefulness of call/cc is when you have an continuation you regret and want to do something else instead or you want to come back to this at a later time. call/cc的用处是当你有一个遗憾而后悔并且想要做其他事情或者你想在以后再回到这个时候。 Lets do the first: 让我们做第一个:

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

Clearly, there is a division which is the continuation when the result of the if is done, but since exit is run the whole thing gets short circuited to return +Inf.0. 显然,有一个除法是if的结果完成时的延续,但是由于exit运行,整个东西被短路返回+ Inf.0。

How would you do that with a procedure without getting it to do the division afterward? 你怎么会用一个程序来做到这一点而不让它在之后进行划分? In this style, you can't. 在这种风格,你不能。

It isn't really magic since Scheme converts your code to Continuation Passing Style(=CPS) and in CPS call/cc is no special. 由于Scheme将您的代码转换为Continuation Passing Style(= CPS)并且在CPS call / cc中没有特殊之处,因此这并不是真正的魔力。 It's not trivial writing code in CPS. 在CPS中编写代码并非易事。

Here's the CPS definition of call/cc 这是call/cc的CPS定义

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

Congratulations! 恭喜! You've just invented continuation-passing style! 你刚刚发明了延续传递风格! The only difference between what you've done and call/cc is that call/cc does it automatically, and doesn't require you to restructure your code. 你所做的和call/cc之间的唯一区别是call/cc会自动执行,并且不需要你重构你的代码。

A 'continuation' is the entire future of a computation. “延续”是计算的整个未来。 Every point in a computation has a continuation which, in naive terms, you can think of as the current program-counter and current stack. 计算中的每个点都有一个延续,在幼稚的条件下,你可以将其视为当前的程序计数器和当前堆栈。 The Scheme call/cc function conveniently captures the current configuration and packages it up into a function. Scheme call/cc函数可以方便地捕获当前配置并将其打包成一个函数。 When you invoke that function you revert back to that point in the computation. 当您调用该函数时,您将恢复到计算中的那一点。 Thus, a continuation is very different from a function (but the continuation function is, well, a function). 因此,延续与函数非常不同(但是延续函数是一个函数)。

There are two common cases where one typically sees call/cc applied: 有两种常见情况,其中通常会看到应用的call/cc

  1. non-local exit. 非本地出口。 You establish a continuation, do some computation, to abruptly end the computation you invoke the continuation. 你建立一个延续,做一些计算,突然结束你调用延续的计算。

  2. restart/reenter a computation. 重新启动/重新输入计算。 In this case you save the continuation and then call it again as you please. 在这种情况下,您可以保存延续,然后根据需要再次调用它。

Here is an example for case #1: 以下是案例#1的示例:

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

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

And here is an example for case #2: 以下是案例#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

For this case #2 is it worth noting that the continuation brings you back to the top-level read-eval-print loop - which gives you a chance to re-invoke the continuation in this example! 对于这种情况,#2值得注意的是,延续会将您带回到顶级的read-eval-print循环 - 这使您有机会重新调用此示例中的延续!

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

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