导致“包含递归定义的序列表达式被错误编译"的原因是什么? [英] What reasoning lead to `Sequence expression containing recursive definition is compiled incorrectly`

查看:55
本文介绍了导致“包含递归定义的序列表达式被错误编译"的原因是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题尽管尾部调用位置但仅在64位中,堆栈溢出导致发现在阅读答案之后,我对导致发现错误的原因感到好奇,因为我想做得更好提高我解决问题和了解总体拥有成本的技能.

After reading the answer I am curious as to the reasoning that lead to finding the bug as I would like to better improve my skills at resolving problems and understanding TCO.

推荐答案

我的推理是这样的:

在查看计算表达式时谈论尾部调用"可能会产生误导作用-一般来说,实际上没有这种事情(请参见例如

Talking about "tail calls" when looking at a computation expression can be misleading - in general there really isn't such a thing (see e.g. this other answer for one related discussion, though not related to sequence expressions).

因此,调用 gauss 本身不会使堆栈溢出,只有对其进行迭代的代码才可能使堆栈溢出.但是一旦我看到调用代码就像 Seq.nth 之类的东西,那意味着几乎肯定有一个编译器错误,因为"tail yield! ing"模式"中的序列表达式应该进行了优化(不确定这是否是规范的一部分,但我认为它是众所周知的).因此,这只是查看初始复制的哪些部分是必要的情况.

So calling gauss will not itself ever overflow the stack, only the code iterating through it could make it overflow. But once I saw that the calling code was just something like Seq.nth, that meant that there was almost certainly a compiler bug, because the pattern of "tail yield!ing" in a sequence expression is supposed to get optimized (not sure if this is part of the spec, but I think it's fairly well known). So then it was just a case of seeing what parts of the initial repro were necessary.

使用非递归定义替换原始代码中的循环会使repro停止失败,就像删除模式匹配一​​样.我发现对IL并没有帮助(在序列表达式的编译中涉及到很多由编译器生成的机制),我只是尝试在源代码级别上最小化repro并凭经验测试行为.

Replacing loop in the original code with a non-recursive definition made the repro stop failing, as did removing the pattern match. I didn't find looking at the IL helpful (there's so much compiler-generated machinery involved in the compilation of sequence expressions), I just tried minimizing the repro at the source level and empirically testing the behavior.

这篇关于导致“包含递归定义的序列表达式被错误编译"的原因是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆