根据这个答案
/sf/ask/17360801/#671296
所有这些编程语言都是无堆栈的
无堆叠的Python
PyPy
口齿不清
方案
TCL
LUA
鹦鹉VM
它们无堆叠意味着什么?这是否意味着他们不使用调用堆栈?如果他们不使用调用堆栈,他们使用什么?
它们无堆叠意味着什么?这是否意味着他们不使用调用堆栈?
是的,那是对的.
如果他们不使用调用堆栈,他们使用什么?
当然,具体实施方式因语言而异.在Stackless Python中,有一个调度程序,它使用最顶层的框架及其结果启动Python解释器.解释器根据需要逐个处理操作码,直到它到达CALL_FUNCTION
操作码,即您即将进入函数的信号.这会导致调度程序使用相关信息构建新框架,并使用展开标志返回调度程序.从那里开始,调度员重新开始,将解释器指向最顶层的框架.
无堆栈语言出于多种原因避开调用堆栈,但在许多情况下,它被使用以便某些编程结构变得更容易实现.规范的是延续.延续是可以代表任何常用的控制结构的功能非常强大,非常简单的控制结构,你可能已经熟悉了(while
,do
,if
,switch
,等等).
如果这令人困惑,你可能想尝试围绕维基百科的文章,特别是可爱的延续三明治类比:
假设你在冰箱前的厨房里,想着三明治.你在那里继续,并把它放在你的口袋里.然后你从冰箱里拿出一些火鸡和面包,自己做一个三明治,现在坐在柜台上.你在口袋里调用了延续物,你发现自己再次站在冰箱前面,想着一个三明治.但幸运的是,柜台上有一个三明治,用来制作它的所有材料都不见了.所以你吃它.
它们不使用调用堆栈,因为它们以延续传递方式运行.如果您不熟悉尾部调用优化,那么这可能是理解这意味着什么的良好的第一步.
要模拟此模型上的传统调用/返回,而不是按下返回地址并期望帧的其余部分保持不变,调用者将关闭其余代码以及仍然需要的任何变量(其余的都被释放).然后它对被调用者执行尾调用,将此continuation作为参数传递.当被调用者"返回"时,它通过调用此continuation,将返回值作为参数传递给它来实现.
就上述情况而言,它只是一种复杂的函数调用方式.但是,它很好地概括为更复杂的场景:
异常/最终/ etc块非常容易建模 - 如果你可以传递一个"return"延续作为参数,你可以轻松地传递2(或更多).lisp -y"条件处理程序"块(可能会或可能不会将控制权返回给调用者)也很容易 - 为此函数的其余部分传递一个延续,可能会也可能不会被调用.
多个返回值同样变得容易 - 将几个参数传递给continuation.
返回临时/复制不再与函数参数传递不同.这通常可以更容易消除临时性.
尾递归优化是微不足道的 - 调用者只是传递它收到的"返回"延续,而不是捕获一个新的.