Questions tagged «continuation»

2
Y组合器和尾部调用优化
F#中Y组合器的定义是 let rec y f x = f (y f) x f希望将递归子问题的某些延续作为第一个论点。使用yf作为延续,我们可以看到f将应用于后续调用,因为我们可以开发 let y f x = f (y f) x = f (f (y f)) x = f (f (f (y f))) x etc... 问题是,先验的是,该方案无法使用任何尾部调用优化:的确,f中可能存在一些待处理的操作,在这种情况下,我们不能仅仅改变与f相关联的本地堆栈帧。 因此: 一方面,使用Y组合器需要一个与函数本身截然不同的延续。 在其他方面要应用TCO,我们希望f中没有待处理的操作,而仅调用f本身。 您知道这两者可以和解的任何方式吗?就像带累加器技巧的Y或CPS技巧的Y一样?还是有论据证明不可能做到这一点?

3
使用堆栈表示函数调用语义的替代方法有哪些?
我们都知道并喜欢函数调用通常是使用堆栈来实现的。有框架,返回地址,参数等等。 但是,堆栈是实现细节:调用约定可能会做不同的事情(例如,x86快速调用使用(某些)寄存器,MIPS和跟随器使用寄存器窗口,等等),优化甚至可以做其他事情(内联,帧指针省略,尾调用优化..)。 当然,许多机器(如JVM和CLR这样的VM,以及带有PUSH / POP等的x86等实际机器)上都存在方便的堆栈指令,可以很方便地将其用于函数调用,但是在某些情况下,这是可能的以不需要调用堆栈的方式进行编程(我在这里考虑的是Continuation Passing Style,或者消息传递系统中的Actor) 因此,我开始感到奇怪:是否可以在没有堆栈的情况下实现函数调用语义,或者更好地使用不同的数据结构(可能是队列,或者是关联映射?) ,当然,我知道堆栈非常有用。方便(它无处不在的一个原因),但是最近我碰到了一个使我感到奇怪的实现。 你们是否知道是否曾经用任何语言/机器/虚拟机完成过这项工作?如果有的话,有哪些显着的区别和缺点? 编辑:我的直觉是不同的子计算方法可以使用不同的数据结构。例如,lambda演算不是基于堆栈的(函数应用程序的想法通过简化来体现),但是我正在查看一种真实的语言/机器/示例。这就是为什么我要问...

2
没有作为过程实现的延续的例子是什么?
关于SO上的回调和延续之间的区别的有趣讨论引发了这个问题。根据定义,延续是完成计算所需逻辑的抽象表示。在大多数语言中,这表现为一个自变量过程,您可以将需要继续处理的任何值传递给该过程。 用纯函数式语言(其中所有函数都是纯函数并且是头等公民),我认为延续可以完全建模为函数。毕竟,这就是我以前对到目前为止的理解。但是,世界充满了状态(叹息),因此一般定义不需要连续捕获程序状态-它只需要包含意图。 为了帮助我理解,是否可以用功能语言提供一个示例,其中以比功能更抽象的方式表示延续?我知道Scheme可以让您以一流的方式(call / cc)来获取当前的延续,但是即使如此,似乎传递给call / cc的一个参数过程只是以另一种形式给出了当前的延续调用/ cc函数可以将其结果应用到的自变量过程。

1
一流的延续在现代的面向对象的编程语言中有用吗?
连续在功能性编程语言(例如ContHaskell中的monad)中非常有用,因为它们允许对命令式代码进行简单且规则的表示。它们在某些较旧的命令式语言中也很有用,因为它们可用于实现缺少的语言功能(例如,异常,协程,绿色线程)。但对于内置支持这些功能流行的面向对象的语言,什么样的参数会有的还加入了一流的延续支持(无论是更现代的风格定界reset和shift或方案类call-with-current-continuation)? 除了性能和实现的复杂性之外,是否还有反对增加支持的论点?

4
如何保持连续性/回调的代码可读性?
简介:尽管使用了异步代码和回调,是否可以遵循一些完善的最佳实践模式来使代码保持可读性? 我正在使用一个JavaScript库,该库异步执行很多工作,并且严重依赖于回调。看来编写一个简单的“负载A,负载B ...”方法变得相当复杂,并且很难使用此模式进行操作。 让我举一个(人为的)例子。假设我要从远程Web服务器(异步)加载一堆图像。在C#/ async中,我将编写如下内容: disableStartButton(); foreach (myData in myRepository) { var result = await LoadImageAsync("http://my/server/GetImage?" + myData.Id); if (result.Success) { myData.Image = result.Data; } else { write("error loading Image " + myData.Id); return; } } write("success"); enableStartButton(); 代码布局遵循“事件流”:首先,禁用开始按钮,然后加载图像(await确保UI保持响应),然后再次启用开始按钮。 在JavaScript中,使用回调,我想到了这一点: disableStartButton(); var count = myRepository.length; function loadImage(i) { if (i …
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.