没有作为过程实现的延续的例子是什么?


15

关于SO上的回调延续之间的区别的有趣讨论引发了这个问题。根据定义,延续是完成计算所需逻辑的抽象表示。在大多数语言中,这表现为一个自变量过程,您可以将需要继续处理的任何值传递给该过程。

用纯函数式语言(其中所有函数都是纯函数并且是头等公民),我认为延续可以完全建模为函数。毕竟,这就是我以前对到目前为止的理解。但是,世界充满了状态(叹息),因此一般定义不需要连续捕获程序状态-它只需要包含意图。

为了帮助我理解,是否可以用功能语言提供一个示例,其中以比功能更抽象的方式表示延续?我知道Scheme可以让您以一流的方式(call / cc)来获取当前的延续,但是即使如此,似乎传递给call / cc的一个参数过程只是以另一种形式给出了当前的延续调用/ cc函数可以将其结果应用到的自变量过程。


延展和去功能化的交集可能是:延展可以通过去功能化转换为数据结构;可能是一个有趣的领域。
Dan D.

@丹 您对我能读到的有趣文学有什么建议吗?该主题听起来很有用。
大卫·考登

Answers:


11

tl; dr; 该类型是在延续的首要抽象


延续是其输入和输出的类型

您会发现最接近基于非过程的延续的事物可能是Haskell中延续单子,因为它以一种类型表示,为此,许多功能可用于与该类型进行交互以中断,恢复,回溯等。

您可以将该闭包封装为一种类型,例如ContHaskell 中的类型,在该类型中您将monad抽象作为“更高级别的抽象”获得,并且在将延续视为类型而非例如一个简单的过程

  • 你可以采取两种延续,并做他们之间的选择,如果该类型遵循的规律是一个
  • 如果将闭包封装为遵守函子定律的类型,则可以抽象该类型以更改延续的输入或输出类型
  • 如果将闭包封装为遵循应用函子定律的类型,则可以使用输入验证或输入转换等功能任意或部分地应用或修饰延续,

封闭与程序

归根结底,您基本上是对的。延续是一个“过程”,尽管我宁愿称其为闭包。通常,连续性最好表示为封闭环境的一流封闭。用纯函数式语言,您可能会说这不是特别合理,因为您缺少参考。的确如此,但是您可以将值括起来,并且通过一次赋值就可以将值与引用括起来完全一样。这导致了Haskell:

(\x -> \y -> insideYIcanAccess x (and y))

一种缺乏封装绑定环境能力的语言在技术上可能缺少一流的闭包,但是即使那样,仍有某种环境(通常是全局的)可供闭包使用。

因此,我想将延续描述为:将闭包以特定方式使用。


结论

对于“除了程序以外的其他方式,是否可以实施延续?”这一问题 否。如果您没有一流的函数,那么您实际上就不会有延续性(是的,函数指针算作一流的函数,因此,任意内存访问就足够了)。

现在的问题是“有没有比过程更抽象的方式来表达延续的方法了?” 将其表示为一种类型可以为您提供更大的抽象性,使您可以以非常通用的方式来处理连续性,这样您不仅可以执行连续性,还可以通过多种方式与连续性进行交互。


1
这可以概括为“延续可以只是让您获得程序其余部分结果的任何东西”。由于这通常要求拥有一些代码(程序的其余部分),因此大多数语言都使用功能。从理论上讲,您可以构建任何内容的延续。在编译器中进行连续转换时,我使用了部分填充的树。
Daniel Gratzer 2013年

1
@jozefg部分填充的树是将计算正确地表示为表达式的方法,但是最终,实际编写的代码只是某种形式的表达式,与我所理解的过程无法区别。除此之外,部分填充的树是编译器表示。开发人员表示形式期望是一种使用该语言的语法和语义进行规范的计算表达式,对于99%的开发人员来说,它是“过程”,“功能”或其他形式。您是从编译器开发人员的角度思考的吗
Jimmy Hoffa 2013年

2

您可能会喜欢的一个示例是协程。例如,来自Lua的协程或来自Python或C#的迭代器/生成器在功能上与单次延续(仅允许调用一次的延续)相似,但未将延续明确地制成函数。相反,您有办法将协程前进到下一个“ yield”语句。

例如,考虑以下Python程序:

def my_iterator():
   yield 1
   yield 2
   yield 3

def main():
   it = my_iterator()
   x = it.next()
   y = it.next()
   z = it.next()
   print x + y + z

它类似于以下带有显式回调的Javascript程序:

function my_iterator()
  return function(cb1){
    cb1(1, function(cb2){
      cb2(2, function(cb3){
        cb3(3, function(cb4){
          throw "stop iteration";
        });
      });
    });
  });
}

function main(){
   var getNext1 = my_iterator();
   getNext1(function(x, getNext2){
      getNext2(function(y, getNext3){
         getNext3(function(z, getNext4){
            console.log(x + y + z);
         });
      });
   });
}

Javascript示例有点嘈杂,因为除了返回产生的值外,每个步骤还需要返回下一个延续(在Python中跟踪ite中的延续)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.