Haskell中的延续与调用堆栈

Haskell中的延续与调用堆栈,haskell,ghc,Haskell,Ghc,Haskell(GHC)运行时如何知道在计算thunk之后接下来应该执行哪些代码 在概念层面上,这与其他编程语言中的调用堆栈有什么不同(除了在堆上存储闭合变量并具有尾部递归)?GHC(或者更确切地说,GHC RTS)与大多数东西一样,具有正常的调用堆栈 不同的是这个堆栈的内容。这与你的预期不符 假设函数foo调用函数bar,后者调用函数baz。您可能希望调用堆栈看起来像 foo bar baz 在某个时刻。但实际上,当foo调用bar时,“调用”真正做的就是创建一个thunk并立即返回。因此,

Haskell(GHC)运行时如何知道在计算thunk之后接下来应该执行哪些代码

在概念层面上,这与其他编程语言中的调用堆栈有什么不同(除了在堆上存储闭合变量并具有尾部递归)?

GHC(或者更确切地说,GHC RTS)与大多数东西一样,具有正常的调用堆栈

不同的是这个堆栈的内容。这与你的预期不符

假设函数
foo
调用函数
bar
,后者调用函数
baz
。您可能希望调用堆栈看起来像

foo
bar
baz
在某个时刻。但实际上,当
foo
调用
bar
时,“调用”真正做的就是创建一个thunk并立即返回。因此,
bar
在该点不会出现在堆栈上。但是当
foo
向调用者返回一些数据,并且调用者决定对其进行处理时,此时
bar
可能会出现在调用堆栈上,即使
foo
不可见


简言之,调用堆栈上的内容顺序与谁调用谁无关。这取决于谁看什么。

您是否阅读过有关GHC工作原理的任何文档?稍微过时的无刺无标签G-machine纸和GHC评论一起涵盖了这一重要细节。@Daniel,我实际上试图阅读它们,但放弃了。像许多人一样,我通过慢慢地整理一些小信息来学习。阅读论文需要“线性”理解所有提出的概念,包括先决条件。我相信,对这个问题的回答也将有助于其他人在学习Haskell方面迈出一步。与现有文献相比,你希望在SO回答中有什么不同之处?这是一个很大的话题,“一个人必须理解先决条件”并不能通过再次写下答案来改变。我认为@sevo的观点是正确的。许多论文的目标是他们领域的专家,而不是从业者。这就是为什么我们有书籍、教程、指南和这个问答网站。然而,我同意理解先决条件是可取的(如果时间/精力允许的话)。那么最终强制thunk的代码是以类似于C调用约定的方式来实现的?或者它使用的是GHC特定的约定(和堆分配的堆栈),它们在其他方面在原则上是相似的?我在这里有点深奥,但我相信这和这个调用没有什么不同。(thunk评估代码得到一个指向正在评估的thunk的指针。我认为还有其他一些全局指针作为优化。)如果你真的对这些东西感兴趣,请查看GHC代码注释。