Lisp 延续与函数的区别是什么?

Lisp 延续与函数的区别是什么?,lisp,scheme,continuations,callcc,Lisp,Scheme,Continuations,Callcc,Continuation用一些值来描述接下来发生的事情,对吗? 这不只是一个取值并进行计算的函数吗 (+ (* 2 3) 5) (*23)的延续是(++u5) 在这里使用call/cc而不使用k函数有什么意义?正确。所有程序都会继续,直到停止。一个延续通常是基础实现完成的计算中的一个步骤 你的例子是: (+ (* 2 3) 5) 组合+取决于先完成的组合*。因此,(+result 5)实际上是(*23)的延续。但在这种情况下,这不是一个过程。call/cc的有用之处在于,当你有一个续集时,你

Continuation用一些值来描述接下来发生的事情,对吗? 这不只是一个取值并进行计算的函数吗

(+ (* 2 3) 5)
(*23)
的延续是
(++u5)


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

正确。所有程序都会继续,直到停止。一个延续通常是基础实现完成的计算中的一个步骤

你的例子是:

(+ (* 2 3) 5)
组合+取决于先完成的组合*。因此,
(+result 5)
实际上是
(*23)
的延续。但在这种情况下,这不是一个过程。
call/cc
的有用之处在于,当你有一个续集时,你会后悔,想做些别的事情,或者你想以后再做。让我们做第一件事:

(define g 0)
(call/cc 
  (lambda (exit)
    (/ 10 (if (= g 0) (exit +Inf.0) g))))
显然,当if的结果完成时,有一个除法是继续,但是由于
退出
被运行,整个过程会短路,返回+Inf.0

如果不让它在事后进行除法,你会怎么做?在这种风格中,你不能

这并不是很神奇,因为Scheme将您的代码转换为CPS,而在CPS中,call/cc并没有什么特别之处。在CPS中编写代码并不是件小事

以下是CPS对
call/cc

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

恭喜你!你刚刚发明了连续传球的风格!你所做的事情与
call/cc
之间的唯一区别在于
call/cc
自动执行,并且不需要你重新构造代码。

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

有两种常见情况下,通常会应用
call/cc

  • 非本地出口。建立一个延续,进行一些计算,以突然结束调用延续的计算

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

  • 下面是案例1的一个示例:

    下面是案例2的一个例子:


    对于本例#2,值得注意的是,continuation将您带回顶级的read-eval-print循环,这使您有机会在本例中重新调用continuation

    您不能使用参数取当前延续(作为函数)的
    call/cc
    。编辑您的问题以使用
    呼叫/cc
    !阅读wikipage上的“我没有使用call/cc,我使用的是表示延续的等效函数”?延续在语法上是一个函数,但它表示控制传输。它的调用协议不同于函数的调用协议——它应该永远不会返回。
    (define (kcall/cc k consumer)
      (consumer k (lambda (ignore v) (k v))))
    
    (begin
      ;; do stuff
      (call/cc (lambda (k)
                  ;; do more
    
                 ;; oops, must 'abort'
                 (k 'ignore)))
      ;; continue on
      )
    
    > (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