fbpx
维基百科

续体

计算机科学中,续体(英語:continuation,也译作计算续体、续延、延續性),是对计算机程序控制状态的一种抽象表示。续体实化了程序控制状态。可以理解为,续体是一种数据结构,它表示在进程执行中给定点上的计算过程,所建立的数据结构可以被编程语言访问,而不是被运行时环境所隐藏掉。这对实现编程语言的某些控制机制,比如例外处理协程生成器非常有用。

“当前续体”从运行代码的角度看来,是可以从程序执行的当前点导出的续体。续体还被用来提及“头等续体”,它是一种构造,赋予编程语言保存在任何点上的执行状态的能力,并在程序中后来的点上可能多次返回到这一点。

头等续体 编辑

头等续体对一门语言而言是能完全控制指令执行次序的能力。它们可以用来跳转到产生对当前函数调用的那个函数,或者跳转到此前已经退出了的函数。人们可以认为头等续体保存了程序执行状态,注意到真正的头等续体不同于进程映像英语System image是很重要的,它不保存程序数据,只保存执行上下文。这经常采用“续体三明治”譬喻来说明:

假想你正站在厨房冰箱之前,想要一个三明治。你就在这里将一个续体放入口袋里。接着在从冰箱里拿出火鸡肉和面包自己做了一个三明治,然后坐到桌案前。你启用了口袋里的续体,这时发现自己再次站到了冰箱之前,想要一个三明治。幸运的是,在桌案上就有一个三明治,而用于做三明治的材料都没有了。你可以吃三明治了。[1]

在这个譬喻中,三明治是一部份程序数据,比如在分配堆上一个对象,并非去调用“制做三明治”例程并等它返回,这里调用“以当前续体制做三明治”例程,它创建一个三明治并在已脱离执行的续体所保存的地方继续执行。

Scheme是支持续体的第一个完全的生产系统,它最初提供了源自Maclisp的用于例外处理的命名catch/throw[2],后来提供了头等续体算子call/cc英语call-with-current-continuation[3]。Bruce Duba将callcc介入到了SML/NJval callcc : ('a cont -> 'a) -> 'a,这里的'a cont是接受类型为'a的参数的续体的类型;callcc f应用f到当前续体,如果f以参数x调用这个续体,则如同(callcc f)返回x作为结果[4]

续体还被用于计算模型,包括指称语义演员模型进程演算λ演算。这些模型依赖于编程者或语义工程师以所谓的续体传递风格英语continuation-passing style书写数学函数。这意味着每个函数都消费一个函数,它表示与这个函数调用有关的余下计算。要返回一个值,这个函数以一个返回值调用这个续体函数,来中止这个返回一个值的计算。

续体传递风格英语continuation-passing style书写程序的函数式编程者获得了以任意方式操纵控制流程的表达能力。代价是他们必须手工维护控制和续体的不变条件,这通常是高度复杂的任务。

编程语言支持 编辑

很多编程语言以各种名义体现出头等续体,特别是:

  • Common Lisp:cl-cont[5],还可以使用定制宏
  • C# / VB.NETasync/await[6]
  • Factorcallcc0callcc1
  • Haskell:在Control.Monad.Cont中的续体单子[7]
  • Haxe:haxe-continuation[8]
  • Icon / Uniconcreatesuspend@算子(coexpression)
  • Java:Lightwolf[9]和javaflow[10]
  • KotlinContinuation
  • Rhino (JavaScript引擎)Continuation
  • ParrotContinuation PMC,对所有控制流程使用续体传递风格英语continuation-passing style
  • Perl:Coro[11]和Continuity[12]
  • Pico英语Pico (programming language)call(exp())continue(aContinuation, anyValue)
  • PythonPyPy_continuation.continulet[13]
  • Racketcall-with-current-continuation英语call-with-current-continuation(通常简写为call/cc
  • Rubycallcc
  • Scalascala.util.continuations提供了shift/reset
  • Schemecall-with-current-continuation英语call-with-current-continuation(通常简写为call/cc
  • SmalltalkContinuation currentDo:,在多数现代Smalltalk环境中续体不需要额外的VM支持就能实现
  • 新泽西Standard MLSMLofNJ.Cont.callcc

在支持闭包和适当尾递归的任何编程语言中,都可能以续体传递风格英语continuation-passing style书写程序并手工实现call/cc。在续体传递风格下,call/cc成为了可以用lambda书写的一个简单函数。需要支持适当尾递归,因为在续体传递风格下没有函数会返回,所有调用都是尾调用。

Scheme的call/cc 编辑

Scheme编程语言包括了控制流程算子call-with-current-continuation英语call-with-current-continuation(简写为call/cc),Scheme程序可以通过它操纵控制流程。在计算机科学中,使这种类型的隐含程序状态可见为对象,术语上叫做实化。在Scheme中,续体对象是头等值并被表示为函数,具有函数应用英语Function application作为其唯一的运算。Scheme在应用续体和函数二者之间不做语法上的区分。

在Scheme中,出现在一个表达式中的(call/cc f),接受一个函数f作为它的唯一实际参数,并把它应用到这个表达式的当前续体上。当一个续体对象被应用于一个实际参数的时候,现存的续体被消除,而应用的续体在其所在位置上被恢复,所以程序流程将在续体被捕获的那一点上继续,而“续体的实际参数”则变成call/cc调用的“返回值”。call/cc建立的续体可以被多于一次调用,甚至可以从这个call/cc应用的动态时效范围(extent)的外部来调用。

例如在表达式((call/cc f) e)中,在概念上给出f所应用到的当前续体的方式,是通过将(call/cc f)替代为以lambda抽象绑定的一个变量比如叫做c,故而它的当前续体是(lambda (c) (c e))。对它应用函数f,得到最终结果(f (lambda (c) (c e)))。而在表达式(e (call/cc f))中,子表达式的(call/cc f)的续体是(lambda (c) (e c)),故而整个表达式等价于(f (lambda (c) (e c)))

立即返回 编辑

下面的例子中,使用call/cc来模拟C风格语言中的return语句

(define (f return)    (return 2)   3) (f (lambda (x) x)) => 3 (call/cc f) => 2 

首先以正规函数实际参数(lambda (x) x)调用f,它将绑定到形式参数return上的这个函数应用于值2,接着执行下一个表达式返回3。但是,在f被传递给call/cc的时候,将绑定了续体的形式参数应用于2,将程序执行强制为跳转到调用call/cc那一点上,并导致call/cc返回值2。这个结果接着被顶层续体用display函数打印出来。

生成器 编辑

在下面的生成器代码中,call/cc被使用了两处:一处用于生成立即返回续体,而另一处用于遍历一个成员列表的迭代在暂停时保存恢复位置:

(define (generator-factory lst)  (define (control-state return)  (for-each   (lambda (element)  (set! return (call/cc (lambda (resume-here)  (set! control-state resume-here)  (return element)))))  lst)  (return 'fell-off-the-end))  (define (generator)  (call/cc control-state))  generator) 

上述代码的简单用例:

(define generate-digit  (generator-factory '(0 1 2))) (define (display-two-digits)  (display (generate-digit)) (newline)  (display (generate-digit)) (newline)) (display-two-digits) ;; 分两行打印 0 和 1 (display-two-digits) ;; 分两行打印 2 和 fell-off-the-end 

在定义变量generate-digit之时,将其定义为函数generator-factory应用于列表'(0 1 2)上而得到的一个闭包generator。这个generator被定义为(call/cc control-state)

在第一次执行(generate-digit)之时,执行(call/cc control-state),进而执行(control-state return),它将用于立即返回的续体绑定到形式参数return之上;然后开始遍历列表的元素进行迭代的(for-each (lambda (element) ……) lst),在求值(set! return (……))的第二个实际参数之时,进行每一次迭代步骤(call/cc (lambda (resume-here) ……)),其中的(set! control-state resume-here),将绑定到变量resume-here上的当前续体,重新绑定到函数名字control-state之上用于以后恢复执行,最后执行(return element)返回当前列表元素。

在下一次执行(generate-digit)之时,(call/cc control-state)control-state所绑定的续体应用当前续体上,从而在迭代的(set! return (call/cc ……))之处恢复执行,它将传入的立即返回续体绑定到变量return上,此后继续这一次的迭代步骤。在遍历了列表的元素之后迭代结束,最终执行(return 'fell-off-the-end),返回一个约定的文字英语Literal (computer programming)常量。

协程 编辑

call/cc还可以表达其他复杂的原始运算。下面的代码使用续体达成协作式多任务用户级线程,亦称为协程

(define *ready-list* '()) (define (fork fn arg)  (call/cc (lambda (return)  (set! *ready-list* (cons return *ready-list*))  (fn arg)  (let ((cont (car *ready-list*)))  (set! *ready-list* (cdr *ready-list*))   (cont #f))))) (define (yield)  (call/cc (lambda (return)  (let ((cont (car *ready-list*)))  (set! *ready-list*  (append (cdr *ready-list*) (list return)))  (cont #f))))) (define (schedule)  (let loop ()  (if (not (null? *ready-list*)) (begin  (call/cc (lambda (return)  (let ((cont (car *ready-list*)))  (set! *ready-list*   (append (cdr *ready-list*) (list return)))  (cont #f))))  (loop))))) 

上述代码的简单用例[14]

(import (srfi 28)) (define (do-stuff-n-print str)  (let loop ((n 0))  (if (< n 3) (begin  (display (format "~a ~a~%" str n))  ;; 调用退让过程,它捕获调用者的当前续体,  ;; 将其追加到等待线程的列表,本线程暂停。  (yield)  (loop (+ n 1)))))) (define (main)  ;; 调用分叉过程,它接受一个函数和相应的一个参数,  ;; 创建一个新线程运行这个函数。  (fork do-stuff-n-print "This is AAA")  (fork do-stuff-n-print "Hello from BBB")  ;; 调用调度过程,它采用FIFO,只要有任何其他线程等待,  ;; 就取其中第一个线程运行,最终无等待者时结束。  (schedule))   (main) 

其输出为:

This is AAA 0 Hello from BBB 0 This is AAA 1 Hello from BBB 1 This is AAA 2 Hello from BBB 2 

引用与注释 编辑

  1. ^ Palmer, Luke. undo()? ("continuation sandwich" example). perl.perl6.language (newsgroup). June 29, 2004 [2009-10-04]. (原始内容于2013-06-06). 
  2. ^ Kent M. Pitman英语Kent Pitman. The Revised Maclisp Manual. 1983, 2007 [2021-10-15]. (原始内容于2021-12-21). Historically, (CATCH form) evolved to handle the fact that programmers were using (ERRSET (...(ERR)...)) to accomplish non-local returns since there was once no other way to get that functionality. CATCH and THROW were introduced so that programmers could write (CATCH (...(THROW val)...)) instead where there was really no error condition. However, it was found that confusion would often result using unlabelled CATCH/THROW because an unlablled CATCH could catch a throw it hadn't intended to. This is why named CATCH was invented. 
    Gerald J. Sussman, Guy L. Steele Jr..   Scheme: An Interpreter for Extended Lambda Calculus. 维基文库. 1975. CATCH - This is the "escape operator" which gives the user a handle on the control structure of the interpreter. The expression:
    (CATCH <identifier> <expression>)
    evaluates <expression> in an environment where <identifier> is bound to a continuation which is "just about to return from the CATCH"; that is, if the continuation is called as a function of one argument, then control proceeds as if the CATCH expression had returned with the supplied (evaluated) argument as its value. ……
    As another example, we can define a THROW function, which may then be used with CATCH much as they are in LISP:
    (DEFINE THROW (LAMBDA (TAG RESULT) (TAG RESULT)))
     
  3. ^ William Clinger, Daniel P. Friedman, Mitchell Wand. A scheme for a higher-level semantic algebra (PDF). 1985 [2021-10-14]. (原始内容 (PDF)于2022-01-21). 
  4. ^ Bruce Duba, Robert Harper, David MacQueen. Typing first-class continuations in ML (PDF). 1991 [2021-10-11]. (原始内容 (PDF)于2022-01-29). 
  5. ^ cl-cont. [2021-10-11]. (原始内容于2012-03-30). 
  6. ^ C# guide — Task asynchronous programming model — Threads. Async methods are intended to be non-blocking operations. An await expression in an async method doesn't block the current thread while the awaited task is running. Instead, the expression signs up the rest of the method as a continuation and returns control to the caller of the async method. 
  7. ^ Control.Monad.Cont. [2021-10-11]. (原始内容于2012-03-23). 
  8. ^ haxe-continuation. [2021-10-11]. (原始内容于2021-12-25). 
  9. ^ Lightwolf. [2021-10-11]. (原始内容于2021-10-26). 
  10. ^ javaflow (页面存档备份,存于互联网档案馆) (requires bytecode manipulation at runtime or compile time)
  11. ^ Coro. [2021-10-11]. (原始内容于2013-08-06). 
  12. ^ Continuity
  13. ^ _continuation.continulet. [2021-10-11]. (原始内容于2016-04-13). 
  14. ^ 这组代码也可以选用冗余但普适的弹跳床英语trampoline (computing)语义的调度过程:
    (define (schedule)  (let loop ()  (if (not (null? *ready-list*)) (begin  (call/cc (lambda (return)  (let ((cont (car *ready-list*)))  (set! *ready-list*   (cons return (cdr *ready-list*)))  (cont #f))))  (loop))))) 

延伸阅读 编辑

  • Peter Landin. A Generalization of Jumps and Labels Report. UNIVAC Systems Programming Research. August 1965. Reprinted in Higher Order and Symbolic Computation, 11(2):125-143, 1998, with a foreword by Hayo Thielecke.
  • Drew McDermott and Gerald Sussman. The Conniver Reference Manual MIT AI Memo 259. May 1972.
  • Daniel Bobrow: A Model for Control Structures for Artificial Intelligence Programming Languages IJCAI 1973.
  • Carl Hewitt, Peter Bishop and Richard Steiger. A Universal Modular Actor Formalism for Artificial Intelligence IJCAI 1973.
  • Christopher Strachey and Christopher P. Wadsworth. Continuations: a Mathematical semantics for handling full jumps Technical Monograph PRG-11. Oxford University Computing Laboratory. January 1974. Reprinted in Higher Order and Symbolic Computation, 13(1/2):135—152, 2000, with a foreword by Christopher P. Wadsworth.
  • John C. Reynolds. Definitional Interpreters for Higher-Order Programming Languages Proceedings of 25th ACM National Conference, pp. 717–740, 1972. Reprinted in Higher-Order and Symbolic Computation 11(4):363-397, 1998, with a foreword.
  • John C. Reynolds. On the Relation between Direct and Continuation Semantics Proceedings of Second Colloquium on Automata, Languages, and Programming. LNCS Vol. 14, pp. 141–156, 1974.
  • Reynolds, John C. The discoveries of continuations (PDF). Lisp and Symbolic Computation. 1993, 6 (3/4): 233–248 [2021-10-11]. (原始内容 (PDF)于2022-03-20). 
  • Gerald Sussman and Guy Steele. SCHEME: An Interpreter for Extended Lambda Calculus AI Memo 349, MIT Artificial Intelligence Laboratory, Cambridge, Massachusetts, December 1975. Reprinted in Higher-Order and Symbolic Computation 11(4):405-439, 1998, with a foreword.
  • Robert Hieb, R. Kent Dybvig, Carl Bruggeman. Representing Control in the Presence of First-Class Continuations Proceedings of the ACM SIGPLAN '90 Conference on Programming Language Design and Implementation, pp. 66–77.
  • Will Clinger, Anne Hartheimer, Eric Ost. Implementation Strategies for Continuations Proceedings of the 1988 ACM conference on LISP and Functional Programming, pp. 124–131, 1988. Journal version: Higher-Order and Symbolic Computation, 12(1):7-45, 1999.
  • Christian Queinnec. Inverting back the inversion of control or, Continuations versus page-centric programming SIGPLAN Notices 38(2), pp. 57–64, 2003.

外部链接 编辑

  • Continuations for Curmudgeons (页面存档备份,存于互联网档案馆) by Sam Ruby
  • Teach Yourself Scheme in Fixnum Days by Dorai Sitaram features a nice chapter on continuations.
  • Continuations and Stackless Python (页面存档备份,存于互联网档案馆) by Christian Tismer
  • Continuation, functions and jumps
  • http://okmij.org/ftp/continuations/ (页面存档备份,存于互联网档案馆) by Oleg Kiselyov
  • Haskell Continuation
  • Rhino With Continuations
  • Continuations in pure Java from the RIFE2 web application framework
  • Comparison of generators, coroutines, and continuations, source of the above example (页面存档备份,存于互联网档案馆


续体, 在计算机科学中, 英語, continuation, 也译作计算, 续延, 延續性, 是对计算机程序的控制状态的一种抽象表示, 实化了程序控制状态, 可以理解为, 是一种数据结构, 它表示在进程执行中给定点上的计算过程, 所建立的数据结构可以被编程语言访问, 而不是被运行时环境所隐藏掉, 这对实现编程语言的某些控制机制, 比如例外处理, 协程, 生成器非常有用, 当前, 从运行代码的角度看来, 是可以从程序执行的当前点导出的, 还被用来提及, 头等, 它是一种构造, 赋予编程语言保存在任何点上的执行状态的能. 在计算机科学中 续体 英語 continuation 也译作计算续体 续延 延續性 是对计算机程序的控制状态的一种抽象表示 续体实化了程序控制状态 可以理解为 续体是一种数据结构 它表示在进程执行中给定点上的计算过程 所建立的数据结构可以被编程语言访问 而不是被运行时环境所隐藏掉 这对实现编程语言的某些控制机制 比如例外处理 协程 生成器非常有用 当前续体 从运行代码的角度看来 是可以从程序执行的当前点导出的续体 续体还被用来提及 头等续体 它是一种构造 赋予编程语言保存在任何点上的执行状态的能力 并在程序中后来的点上可能多次返回到这一点 目录 1 头等续体 2 编程语言支持 3 Scheme的call cc 3 1 立即返回 3 2 生成器 3 3 协程 4 引用与注释 5 延伸阅读 6 外部链接头等续体 编辑头等续体对一门语言而言是能完全控制指令执行次序的能力 它们可以用来跳转到产生对当前函数调用的那个函数 或者跳转到此前已经退出了的函数 人们可以认为头等续体保存了程序执行状态 注意到真正的头等续体不同于进程映像 英语 System image 是很重要的 它不保存程序数据 只保存执行上下文 这经常采用 续体三明治 譬喻来说明 假想你正站在厨房冰箱之前 想要一个三明治 你就在这里将一个续体放入口袋里 接着在从冰箱里拿出火鸡肉和面包自己做了一个三明治 然后坐到桌案前 你启用了口袋里的续体 这时发现自己再次站到了冰箱之前 想要一个三明治 幸运的是 在桌案上就有一个三明治 而用于做三明治的材料都没有了 你可以吃三明治了 1 在这个譬喻中 三明治是一部份程序数据 比如在分配堆上一个对象 并非去调用 制做三明治 例程并等它返回 这里调用 以当前续体制做三明治 例程 它创建一个三明治并在已脱离执行的续体所保存的地方继续执行 Scheme是支持续体的第一个完全的生产系统 它最初提供了源自Maclisp的用于例外处理的命名catch throw 2 后来提供了头等续体算子 span class ilh all data orig title 以当前续体调用 data lang code en data lang name 英语 data foreign title call with current continuation span class ilh page call cc span span class noprint ilh comment span class ilh lang 英语 span span class ilh colon span span class ilh link span lang en dir auto call with current continuation span span span span 3 Bruce Duba将callcc介入到了SML NJ span class kr val span span class nv callcc span span class p span span class p span span class nd a span span class n cont span span class p gt span span class nd a span span class p span span class p gt span span class nd a span 这里的 a cont是接受类型为 a的参数的续体的类型 callcc f应用f到当前续体 如果f以参数x调用这个续体 则如同 callcc f 返回x作为结果 4 续体还被用于计算模型 包括指称语义 演员模型 进程演算和l演算 这些模型依赖于编程者或语义工程师以所谓的续体传递风格 英语 continuation passing style 书写数学函数 这意味着每个函数都消费一个函数 它表示与这个函数调用有关的余下计算 要返回一个值 这个函数以一个返回值调用这个续体函数 来中止这个返回一个值的计算 以续体传递风格 英语 continuation passing style 书写程序的函数式编程者获得了以任意方式操纵控制流程的表达能力 代价是他们必须手工维护控制和续体的不变条件 这通常是高度复杂的任务 编程语言支持 编辑很多编程语言以各种名义体现出头等续体 特别是 Common Lisp cl cont 5 还可以使用定制宏 C VB NET async await 6 Factor callcc0和callcc1 Haskell 在Control Monad Cont中的续体单子 7 Haxe haxe continuation 8 Icon Unicon create suspend 算子 coexpression Java Lightwolf 9 和javaflow 10 Kotlin Continuation Rhino JavaScript引擎 Continuation Parrot Continuation PMC 对所有控制流程使用续体传递风格 英语 continuation passing style Perl Coro 11 和Continuity 12 Pico 英语 Pico programming language call exp 和 continue aContinuation anyValue Python PyPy的 continuation continulet 13 Racket span class ilh all data orig title 以当前续体调用 data lang code en data lang name 英语 data foreign title call with current continuation span class ilh page call with current continuation span span class noprint ilh comment span class ilh lang 英语 span span class ilh colon span span class ilh link span lang en dir auto call with current continuation span span span span 通常简写为call cc Ruby callcc Scala scala util continuations提供了shift reset Scheme span class ilh all data orig title 以当前续体调用 data lang code en data lang name 英语 data foreign title call with current continuation span class ilh page call with current continuation span span class noprint ilh comment span class ilh lang 英语 span span class ilh colon span span class ilh link span lang en dir auto call with current continuation span span span span 通常简写为call cc Smalltalk Continuation currentDo 在多数现代Smalltalk环境中续体不需要额外的VM支持就能实现 新泽西Standard ML SMLofNJ Cont callcc 在支持闭包和适当尾递归的任何编程语言中 都可能以续体传递风格 英语 continuation passing style 书写程序并手工实现call cc 在续体传递风格下 call cc成为了可以用lambda书写的一个简单函数 需要支持适当尾递归 因为在续体传递风格下没有函数会返回 所有调用都是尾调用 Scheme的call cc 编辑主条目 以当前续体调用 英语 call with current continuation Scheme编程语言包括了控制流程算子call with current continuation 英语 call with current continuation 简写为call cc Scheme程序可以通过它操纵控制流程 在计算机科学中 使这种类型的隐含程序状态可见为对象 术语上叫做实化 在Scheme中 续体对象是头等值并被表示为函数 具有函数应用 英语 Function application 作为其唯一的运算 Scheme在应用续体和函数二者之间不做语法上的区分 在Scheme中 出现在一个表达式中的 span class p span span class nb call cc span span class w span span class nv f span span class p span 接受一个函数f作为它的唯一实际参数 并把它应用到这个表达式的当前续体上 当一个续体对象被应用于一个实际参数的时候 现存的续体被消除 而应用的续体在其所在位置上被恢复 所以程序流程将在续体被捕获的那一点上继续 而 续体的实际参数 则变成call cc调用的 返回值 call cc建立的续体可以被多于一次调用 甚至可以从这个call cc应用的动态时效范围 extent 的外部来调用 例如在表达式 span class p span span class nb call cc span span class w span span class nv f span span class p span span class w span span class nv e span span class p span 中 在概念上给出f所应用到的当前续体的方式 是通过将 span class p span span class nb call cc span span class w span span class nv f span span class p span 替代为以lambda抽象绑定的一个变量比如叫做c 故而它的当前续体是 span class p span span class k lambda span span class w span span class p span span class nf c span span class p span span class w span span class p span span class nf c span span class w span span class nv e span span class p span 对它应用函数f 得到最终结果 span class p span span class nf f span span class w span span class p span span class k lambda span span class w span span class p span span class nf c span span class p span span class w span span class p span span class nf c span span class w span span class nv e span span class p span 而在表达式 span class p span span class nf e span span class w span span class p span span class nb call cc span span class w span span class nv f span span class p span 中 子表达式的 span class p span span class nb call cc span span class w span span class nv f span span class p span 的续体是 span class p span span class k lambda span span class w span span class p span span class nf c span span class p span span class w span span class p span span class nf e span span class w span span class nv c span span class p span 故而整个表达式等价于 span class p span span class nf f span span class w span span class p span span class k lambda span span class w span span class p span span class nf c span span class p span span class w span span class p span span class nf e span span class w span span class nv c span span class p span 立即返回 编辑 下面的例子中 使用call cc来模拟C风格语言中的return语句 define f return return 2 3 f lambda x x gt 3 call cc f gt 2 首先以正规函数实际参数 span class p span span class k lambda span span class w span span class p span span class nf x span span class p span span class w span span class nv x span span class p span 调用f 它将绑定到形式参数return上的这个函数应用于值2 接着执行下一个表达式返回3 但是 在f被传递给call cc的时候 将绑定了续体的形式参数应用于2 将程序执行强制为跳转到调用call cc那一点上 并导致call cc返回值2 这个结果接着被顶层续体用display函数打印出来 生成器 编辑 在下面的生成器代码中 call cc被使用了两处 一处用于生成立即返回续体 而另一处用于遍历一个成员列表的迭代在暂停时保存恢复位置 define generator factory lst define control state return for each lambda element set return call cc lambda resume here set control state resume here return element lst return fell off the end define generator call cc control state generator 上述代码的简单用例 define generate digit generator factory 0 1 2 define display two digits display generate digit newline display generate digit newline display two digits 分两行打印 0 和 1 display two digits 分两行打印 2 和 fell off the end 在定义变量generate digit之时 将其定义为函数generator factory应用于列表 0 1 2 上而得到的一个闭包generator 这个generator被定义为 span class p span span class nb call cc span span class w span span class nv control state span span class p span 在第一次执行 generate digit 之时 执行 span class p span span class nb call cc span span class w span span class nv control state span span class p span 进而执行 control state return 它将用于立即返回的续体绑定到形式参数return之上 然后开始遍历列表的元素进行迭代的 span class p span span class nb for each span span class w span span class p span span class k lambda span span class w span span class p span span class nf element span span class p span span class w span span class err span span class p span span class w span span class nv lst span span class p span 在求值 span class p span span class k set span span class w span span class nv return span span class w span span class p span span class err span span class p span 的第二个实际参数之时 进行每一次迭代步骤 span class p span span class nb call cc span span class w span span class p span span class k lambda span span class w span span class p span span class nf resume here span span class p span span class w span span class err span span class p span 其中的 span class p span span class k set span span class w span span class nv control state span span class w span span class nv resume here span span class p span 将绑定到变量resume here上的当前续体 重新绑定到函数名字control state之上用于以后恢复执行 最后执行 return element 返回当前列表元素 在下一次执行 generate digit 之时 span class p span span class nb call cc span span class w span span class nv control state span span class p span 将control state所绑定的续体应用当前续体上 从而在迭代的 span class p span span class k set span span class w span span class nv return span span class w span span class p span span class nb call cc span span class w span span class err span span class p span 之处恢复执行 它将传入的立即返回续体绑定到变量return上 此后继续这一次的迭代步骤 在遍历了列表的元素之后迭代结束 最终执行 return fell off the end 返回一个约定的文字 英语 Literal computer programming 常量 协程 编辑 call cc还可以表达其他复杂的原始运算 下面的代码使用续体达成协作式多任务的用户级线程 亦称为协程 define ready list define fork fn arg call cc lambda return set ready list cons return ready list fn arg let cont car ready list set ready list cdr ready list cont f define yield call cc lambda return let cont car ready list set ready list append cdr ready list list return cont f define schedule let loop if not null ready list begin call cc lambda return let cont car ready list set ready list append cdr ready list list return cont f loop 上述代码的简单用例 14 import srfi 28 define do stuff n print str let loop n 0 if lt n 3 begin display format a a str n 调用退让过程 它捕获调用者的当前续体 将其追加到等待线程的列表 本线程暂停 yield loop n 1 define main 调用分叉过程 它接受一个函数和相应的一个参数 创建一个新线程运行这个函数 fork do stuff n print This is AAA fork do stuff n print Hello from BBB 调用调度过程 它采用FIFO 只要有任何其他线程等待 就取其中第一个线程运行 最终无等待者时结束 schedule main 其输出为 This is AAA 0 Hello from BBB 0 This is AAA 1 Hello from BBB 1 This is AAA 2 Hello from BBB 2引用与注释 编辑 Palmer Luke undo continuation sandwich example perl perl6 language newsgroup June 29 2004 2009 10 04 原始内容存档于2013 06 06 Kent M Pitman 英语 Kent Pitman The Revised Maclisp Manual 1983 2007 2021 10 15 原始内容存档于2021 12 21 Historically CATCH form evolved to handle the fact that programmers were using ERRSET ERR to accomplish non local returns since there was once no other way to get that functionality CATCH and THROW were introduced so that programmers could write CATCH THROW val instead where there was really no error condition However it was found that confusion would often result using unlabelled CATCH THROW because an unlablled CATCH could catch a throw it hadn t intended to This is why named CATCH was invented 请检查 date 中的日期值 帮助 Gerald J Sussman Guy L Steele Jr nbsp Scheme An Interpreter for Extended Lambda Calculus 维基文库 1975 CATCH This is the escape operator which gives the user a handle on the control structure of the interpreter The expression CATCH lt identifier gt lt expression gt evaluates lt expression gt in an environment where lt identifier gt is bound to a continuation which is just about to return from the CATCH that is if the continuation is called as a function of one argument then control proceeds as if the CATCH expression had returned with the supplied evaluated argument as its value As another example we can define a THROW function which may then be used with CATCH much as they are in LISP DEFINE THROW LAMBDA TAG RESULT TAG RESULT William Clinger Daniel P Friedman Mitchell Wand A scheme for a higher level semantic algebra PDF 1985 2021 10 14 原始内容存档 PDF 于2022 01 21 Bruce Duba Robert Harper David MacQueen Typing first class continuations in ML PDF 1991 2021 10 11 原始内容存档 PDF 于2022 01 29 cl cont 2021 10 11 原始内容存档于2012 03 30 C guide Task asynchronous programming model Threads Async methods are intended to be non blocking operations An await expression in an async method doesn t block the current thread while the awaited task is running Instead the expression signs up the rest of the method as a continuation and returns control to the caller of the async method Control Monad Cont 2021 10 11 原始内容存档于2012 03 23 haxe continuation 2021 10 11 原始内容存档于2021 12 25 Lightwolf 2021 10 11 原始内容存档于2021 10 26 javaflow 页面存档备份 存于互联网档案馆 requires bytecode manipulation at runtime or compile time Coro 2021 10 11 原始内容存档于2013 08 06 Continuity continuation continulet 2021 10 11 原始内容存档于2016 04 13 这组代码也可以选用冗余但普适的弹跳床 英语 trampoline computing 语义的调度过程 define schedule let loop if not null ready list begin call cc lambda return let cont car ready list set ready list cons return cdr ready list cont f loop 延伸阅读 编辑Peter Landin A Generalization of Jumps and Labels Report UNIVAC Systems Programming Research August 1965 Reprinted in Higher Order and Symbolic Computation 11 2 125 143 1998 with a foreword by Hayo Thielecke Drew McDermott and Gerald Sussman The Conniver Reference Manual MIT AI Memo 259 May 1972 Daniel Bobrow A Model for Control Structures for Artificial Intelligence Programming Languages IJCAI 1973 Carl Hewitt Peter Bishop and Richard Steiger A Universal Modular Actor Formalism for Artificial Intelligence IJCAI 1973 Christopher Strachey and Christopher P Wadsworth Continuations a Mathematical semantics for handling full jumps Technical Monograph PRG 11 Oxford University Computing Laboratory January 1974 Reprinted in Higher Order and Symbolic Computation 13 1 2 135 152 2000 with a foreword by Christopher P Wadsworth John C Reynolds Definitional Interpreters for Higher Order Programming Languages Proceedings of 25th ACM National Conference pp 717 740 1972 Reprinted in Higher Order and Symbolic Computation 11 4 363 397 1998 with a foreword John C Reynolds On the Relation between Direct and Continuation Semantics Proceedings of Second Colloquium on Automata Languages and Programming LNCS Vol 14 pp 141 156 1974 Reynolds John C The discoveries of continuations PDF Lisp and Symbolic Computation 1993 6 3 4 233 248 2021 10 11 原始内容存档 PDF 于2022 03 20 Gerald Sussman and Guy Steele SCHEME An Interpreter for Extended Lambda Calculus AI Memo 349 MIT Artificial Intelligence Laboratory Cambridge Massachusetts December 1975 Reprinted in Higher Order and Symbolic Computation 11 4 405 439 1998 with a foreword Robert Hieb R Kent Dybvig Carl Bruggeman Representing Control in the Presence of First Class Continuations Proceedings of the ACM SIGPLAN 90 Conference on Programming Language Design and Implementation pp 66 77 Will Clinger Anne Hartheimer Eric Ost Implementation Strategies for Continuations Proceedings of the 1988 ACM conference on LISP and Functional Programming pp 124 131 1988 Journal version Higher Order and Symbolic Computation 12 1 7 45 1999 Christian Queinnec Inverting back the inversion of control or Continuations versus page centric programming SIGPLAN Notices 38 2 pp 57 64 2003 外部链接 编辑Continuations for Curmudgeons 页面存档备份 存于互联网档案馆 by Sam Ruby Teach Yourself Scheme in Fixnum Days by Dorai Sitaram features a nice chapter on continuations Continuations and Stackless Python 页面存档备份 存于互联网档案馆 by Christian Tismer Continuation functions and jumps http okmij org ftp continuations 页面存档备份 存于互联网档案馆 by Oleg Kiselyov Haskell Continuation Rhino With Continuations Continuations in pure Java from the RIFE2 web application framework Comparison of generators coroutines and continuations source of the above example 页面存档备份 存于互联网档案馆 取自 https zh wikipedia org w index php title 续体 amp oldid 80877393, 维基百科,wiki,书籍,书籍,图书馆,

文章

,阅读,下载,免费,免费下载,mp3,视频,mp4,3gp, jpg,jpeg,gif,png,图片,音乐,歌曲,电影,书籍,游戏,游戏。