所以我之前已经阅读了很多次,技术上.NET 确实支持尾调用优化(TCO),因为它有操作码,只有C#不生成它.
我不确定为什么TCO需要操作码或它会做什么.据我所知,能够进行TCO的要求是递归调用的结果不与当前函数范围中的任何变量组合.如果你没有那个,那么我看不到操作码如何阻止你必须保持堆栈框架打开.如果你有,那么编译器是否总能轻易地将其编译为迭代的东西?
那么操作码有什么意义呢?显然有一些我不知道的东西.在完全可以使用TCO的情况下,不能总是在编译器级别处理,而不是在操作码级别处理?什么是不能的例子?
我有一个天真的游戏循环实现
let gameLoop gamestate =
let rec innerLoop prev gamestate =
let now = getTicks()
let delta = now - prev
gamestate
|> readInput delta
|> update delta
|> render delta
|> innerLoop delta
innerLoop 0L gamestate
Run Code Online (Sandbox Code Playgroud)
此实现抛出stackoverflowexception.在我看来,这应该是尾递归.我可以像这样做一个工作
let gameLoop gamestate =
let rec innerLoop prev gamestate =
let now = getTicks()
let delta = now - prev
let newState = gamestate
|> readInput delta
|> update delta
|> render delta
innerLoop now newState
innerLoop 0L gamestate
Run Code Online (Sandbox Code Playgroud)
所以我的问题是为什么第一个代码示例抛出stackoverflow异常.