为什么 Haskell 中 Int 的标准保证范围恰好是 [-2^29; 2^29)?

gre*_*ake 8 haskell

为什么范围如此具体?为什么不是 29 位宽或 32 位宽,为什么是 30 位宽?

理由是什么?标准(1)似乎没有给出它

Qqw*_*qwy 6

我最终在Haskell Discourse 论坛上询问了这个谜团,那里提出了多种理论,直到一位用户能够确认这很可能确实是因为耶鲁哈斯克尔(正如 该评论已经推测的那样)。

Yale Haskell 将 Haskell 程序编译为 Common Lisp 程序。(具体来说,Yale Haskell 旨在在 Lucid Common Lisp、CMU Common Lisp (CMUCL) 或 Armed Bear Common Lisp (AKCL) 上运行)。Lisp(与 Haskell 不同)是一种完全动态类型的编程语言,需要在运行时保留所有类型信息。

CMUCL 采取的方法是使用三个较低位作为此类型信息的所有运行时值的标记 [1, 2]。为“偶数”和“奇数”小整数 ( s) 保留了两个位模式fixnum,以提供 30 位范围。

因此,如果将 Haskell 程序编译为 Common Lisp 程序,并且目的是fixnum为 Haskell重新使用 Lisp Int,那么它们的有效范围将仅为 30 位,换句话说就是范围[-2^29..2^29-1]


在现代,这些都不再重要了,原因如下:

  • Yale Haskell 已于大约停产。1995年[3]。GHC Haskell 编译为机器代码而不是 Lisp,能够使用完整的 32 位/64 位范围Int
  • CMU Common Lisp 仍然存在,而且仍然只是 32 位。但在 Common Lisp 社区中,它似乎已经被1999 年从它分叉出来的Steel Bank Common Lisp (SBCL)所取代。SBCL 对 s 使用不同的内部表示。fixnum
  • 现代硬件具有非常不同的约束:紧凑的内存使用不如内联算术和取悦分支预测器重要。例如,CMUCL 的标记方法与 IEEE 浮点数不兼容,这可能就是当今使用其他技术的原因。

  1. CMU 关于标记的内部文档
  2. CMU 内部文档专门介绍了 Fixnum
  3. Haskell 的历史:课堂上的懒惰