17

根据这个答案

https://stackoverflow.com/questions/551950/what-stackless-programming-languages-are-available/671296#671296

所有这些编程语言都是无堆栈的

  • 无堆栈 Python
  • 派皮
  • 语言
  • 方案
  • Tcl
  • 卢阿
  • 鹦鹉虚拟机

对他们来说,无堆栈到底意味着什么?这是否意味着他们不使用调用堆栈?如果他们不使用调用堆栈,他们使用什么?

4

2 回答 2

17

对他们来说,无堆栈到底意味着什么?这是否意味着他们不使用调用堆栈?

是的,这差不多。

如果他们不使用调用堆栈,他们使用什么?

当然,具体的实现会因语言而异。在 Stackless Python 中,有一个调度程序使用最顶层的帧及其结果启动 Python 解释器。解释器根据需要一次处理一个操作码,直到它到达一个CALL_FUNCTION操作码,即您即将进入函数的信号。这会导致调度程序使用相关信息构建一个新框架并返回带有展开标志的调度程序。从那里,调度程序重新开始,将解释器指向最顶层的帧。

出于多种原因,无堆栈语言避开调用堆栈,但在许多情况下,它的使用是为了使某些编程结构变得更容易实现。规范的是continuations。延续是非常强大、非常简单的控制结构,可以表示您可能已经熟悉的任何常用控制结构(whiledoifswitch等)。

如果这令人困惑,您可能想尝试围绕维基百科的文章,特别是可爱的延续三明治类比

假设你在冰箱前的厨房里,想着三明治。你在那里拿一个延续,把它放在你的口袋里。然后你从冰箱里拿出一些火鸡和面包,给自己做一个三明治,现在放在柜台上。你调用你口袋里的延续,你发现自己又站在冰箱前,想着一个三明治。不过好在柜台上有一个三明治,所有用来做三明治的材料都没有了。所以你吃它。

于 2009-04-28T04:32:59.297 回答
12

它们不使用调用堆栈,因为它们以continuation-passing style运行。如果您不熟悉尾调用优化,那么这可能是了解其含义的良好第一步。

为了在此模型上模拟传统的调用/返回,而不是推送返回地址并期望帧的其余部分保持不变,调用者关闭其代码的其余部分和仍然需要的任何变量(其余部分被释放)。然后它对被调用者执行尾调用,将此延续作为参数传递。当被调用者“返回”时,它通过调用这个延续,将返回值作为参数传递给它。

就上述内容而言,这只是一种进行函数调用的复杂方法。但是,它可以很好地推广到更复杂的场景:

  1. exception/finally/etc 块很容易建模 - 如果你可以传递一个“返回”延续作为参数,你可以很容易地传递 2(或更多)。lisp-y“条件处理程序”块(可能会或可能不会将控制权返回给调用者)也很容易 - 为这个函数的其余部分传递一个延续,它可能会或可能不会被调用。
  2. 多个返回值同样变得容易 - 将多个参数传递给延续。
  3. 返回临时/复制不再与函数参数传递不同。这通常可以更容易地消除临时性。
  4. 尾递归优化是微不足道的——调用者只是传递它收到的“返回”延续而不是捕获一个新的延续。
于 2009-04-28T04:51:01.750 回答