&lt; <loop>&gt;如何?错误&#34;工作&#34;详细地?

时间:2017-01-07 03:29:52

标签: haskell ghc

我正在使用这个工具,用户可以在[config files |中定义 - 并包含它内容文本文件|他们自己的&#34;模板&#34; (像胡子等),这些可以引用其他人,因此他们可以诱导循环。正当我即将创建一个&#34; max-loops&#34;设置我用runghc实现了程序一段时间之后只退出了<<loop>>的告别消息。这对我来说实际上已经足够好了但引起了一些争议:

  • GHC或运行时如何实际检测到它被卡在一个循环中,它如何区分所需的长时间运行操作和偶然的无限循环?暂停问题仍然是我检查的最后一件事..

  • 可以自定义设置给编译器或运行时的任何(时间或迭代)限制吗?

  • runghc - 仅在所有最终编译输出中是否存在?

  • 在构建版本时,如果稍后设置-o(优化)标志会禁用这种明显的内置循环检测吗?

所有的东西我当然可以找出困难的方法,但谁知道也许有人已经更详细地研究了这个...(很难为"haskell" "<<loop>>" google / ddg,因为他们剥去尖括号然后显示结果&#34;如何在Haskell&#34;等循环。)

1 个答案:

答案 0 :(得分:5)

这是在GHC中实现的STG运行时的简单“改进”。我会分享我所理解的内容,但GHC专家可能会提供更有用和准确的信息。

GHC在完成多项优化后编译成一种名为Core的中间语言。您可以使用ghc -ddump-simpl ...

查看

非常粗略地说,在Core中,未评估的绑定(如let x = 1+y+x in f x)会产生一个thunk。一些内存被分配到某个地方来表示闭包,x被指向它。

x强制{和{{}} f时,将评估thunk。以下是改进:在评估开始之前,x的thunk被一个名为BLACKHOLE的特殊值覆盖。在评估x之后(对WHNF),黑洞再次被实际值覆盖(因此我们不会重新计算它,例如f x = x+x)。

如果强行黑洞,则会触发<<loop>>。这实际上是一个IO异常(那些也可以在纯代码中引发,所以这很好)。

示例:

let x = 1+x in 2*x          -- <<loop>>
let g x = g (x+1) in  g 0   -- diverges
let h x = h (10-x) in h 0   -- diverges, even if h 0 -> h 10 -> h 0 -> ...
let g0 = g10 ; g10 = g0 in g0   -- <<loop>>

请注意,h 0的每次调用都被认为是一个明显的thunk,因此不会强迫黑洞。

棘手的部分是,理解哪些thunk实际上是在Core中创建并不是完全无足轻重的,因为GHC可以在发布Core之前执行多次优化。因此,我们应该将<<loop>>视为奖励,而不是GHC的给定/硬性保证。未来的新优化可能会将某些<<loop>>替换为实际的非终止。

如果你想谷歌的东西,“GHC,blackhole,STG”应该是很好的关键词。