scala 编译器堆栈溢出保护
scala compiler's stackoverflow protection
在运行时我可以:
def X(R: Any): Any = X(R)
但是不能在编译时做类似的事情:
scala> type X[R] = X[R]
<console>:11: error: illegal cyclic reference involving type X
type X[R] = X[R]
^
似乎是无限的 loop/recursion 保护,但据我了解 Halting problem - there is no general way to detect infinite recursion for turing-complete 语言(因为检测器本身可能不会停止),因此额外的编译器检查通常不会在这里工作。
那么有没有办法在 scalac 上实现无限递归?而且,还有其他原因(除了防止这种递归)有 illegal cyclic reference
吗?
使用递归结合多态性,有一种在 scalac 上获取 Whosebug 的棘手方法:
scala> trait Re { type X[R <: Re] }
warning: there were 1 feature warning(s); re-run with -feature for details
defined trait Re
scala> trait ReRe extends Re {type X[R <: Re] = R#X[R]}
defined trait ReRe
scala> type X = ReRe#X[ReRe]
java.lang.WhosebugError
之所以有效,是因为编译器认为R#X[R]
是在Re
上调用的,但实际上在计算type X
时传递了ReRe
。
不知道 illegal cyclic reference
的目的 - 也许它只能防止编译器内部的无限循环,但不能防止无限递归(如果图灵完备性是使用非尾递归实现的)。
在运行时我可以:
def X(R: Any): Any = X(R)
但是不能在编译时做类似的事情:
scala> type X[R] = X[R]
<console>:11: error: illegal cyclic reference involving type X
type X[R] = X[R]
^
似乎是无限的 loop/recursion 保护,但据我了解 Halting problem - there is no general way to detect infinite recursion for turing-complete 语言(因为检测器本身可能不会停止),因此额外的编译器检查通常不会在这里工作。
那么有没有办法在 scalac 上实现无限递归?而且,还有其他原因(除了防止这种递归)有 illegal cyclic reference
吗?
使用递归结合多态性,有一种在 scalac 上获取 Whosebug 的棘手方法:
scala> trait Re { type X[R <: Re] }
warning: there were 1 feature warning(s); re-run with -feature for details
defined trait Re
scala> trait ReRe extends Re {type X[R <: Re] = R#X[R]}
defined trait ReRe
scala> type X = ReRe#X[ReRe]
java.lang.WhosebugError
之所以有效,是因为编译器认为R#X[R]
是在Re
上调用的,但实际上在计算type X
时传递了ReRe
。
不知道 illegal cyclic reference
的目的 - 也许它只能防止编译器内部的无限循环,但不能防止无限递归(如果图灵完备性是使用非尾递归实现的)。