是什么原因导致“包含递归定义的序列表达式被错误编译”
What reasoning lead to `Sequence expression containing recursive definition is compiled incorrectly`
F#编译器中的问题 lead to uncovering a bug。
阅读 后,我很好奇导致发现错误的推理,因为我想更好地提高解决问题和理解 TCO 的技能。
我的推理是这样的:
在查看计算表达式时谈论 "tail calls" 可能会产生误导 - 一般来说,确实没有这样的事情(参见 this other answer 的相关讨论,尽管与 序列表达式)。
因此调用 gauss
本身不会溢出堆栈,只有迭代它的代码才能使其溢出。但是一旦我看到调用代码就像 Seq.nth
,这意味着几乎可以肯定存在编译器错误,因为序列表达式中 "tail yield!
ing" 的模式应该得到优化(不确定如果这是规范的一部分,但我认为这是众所周知的)。因此,这只是一个查看初始复制的哪些部分是必要的情况。
用非递归定义替换原始代码中的循环使重现停止失败,删除模式匹配也是如此。我没有发现查看 IL 有帮助(在序列表达式的编译中涉及很多编译器生成的机制),我只是尝试在源代码级别最小化 repro 并根据经验测试行为。
F#编译器中的问题
阅读
我的推理是这样的:
在查看计算表达式时谈论 "tail calls" 可能会产生误导 - 一般来说,确实没有这样的事情(参见 this other answer 的相关讨论,尽管与 序列表达式)。
因此调用 gauss
本身不会溢出堆栈,只有迭代它的代码才能使其溢出。但是一旦我看到调用代码就像 Seq.nth
,这意味着几乎可以肯定存在编译器错误,因为序列表达式中 "tail yield!
ing" 的模式应该得到优化(不确定如果这是规范的一部分,但我认为这是众所周知的)。因此,这只是一个查看初始复制的哪些部分是必要的情况。
用非递归定义替换原始代码中的循环使重现停止失败,删除模式匹配也是如此。我没有发现查看 IL 有帮助(在序列表达式的编译中涉及很多编译器生成的机制),我只是尝试在源代码级别最小化 repro 并根据经验测试行为。