GHC 内部结构:类型系统是不是有 C 实现?
Posted
技术标签:
【中文标题】GHC 内部结构:类型系统是不是有 C 实现?【英文标题】:GHC internals: is there C implementation of the type system?GHC 内部结构:类型系统是否有 C 实现? 【发布时间】:2017-10-09 00:14:29 【问题描述】:我正在研究 GHC 的内部结构,我发现所有的解析和类型系统都完全用 Haskell 编写。语言的底层核心由RTS 提供。问题是下列哪一项是正确的?
RTS包含类型系统的C实现和Haskell的其他基础部分(我没找到,RTS主要是GC和线程) 一切都在 Haskell 中实现。但这似乎很棘手,因为构建 GHC 已经需要 GHC。你能解释一下编译器的开发逻辑吗?例如,Python internals 提供了 C 中所有内容的不透明实现。
【问题讨论】:
类型被编译删除。 RTS 对类型一无所知,它只实现了 STG 机器(现在采用 eval/apply 样式),这是一种处理闭包、thunk 等的有效技术。RTS 还实现了 GC,以及一些与 C 级别接口的 FFI。 除了以上内容,我认为一切都在 Haskell 中。没有以前的 GHC 就无法编译 GHC,就像没有以前的 GCC 就无法编译 GCC。我猜 GHC 的早期版本可以从 C 或其他一些 Haskell 编译器/解释器引导,而后者又可以引导。 所以,一切(例如类型推断)都是在 Haskell 中实现的。然后 STG 接收评估的低级表示并在没有任何类型检查的情况下执行它,仅使用值进行操作? 是的,STG 不执行类型检查。在许多静态类型的编程语言中,仅在编译时检查类型,然后可以丢弃(擦除),以便在运行时不会因类型而产生开销。在 GHC 中,静态类型检查器在 Haskell 中实现。 如果你真的想看到用 C 实现的 Haskell 类型系统,无论出于何种原因,Hugs98 中都有一个(参见src/type.c
)。
【参考方案1】:
正如其他人在 cmets 中指出的那样,GHC 几乎完全是编写的 在 Haskell 中(加上选择 GHC 扩展),旨在与自身一起编译。事实上,世界上唯一能编译 GHC 编译器的程序就是 GHC 编译器!特别是, 解析和类型推断是在 Haskell 代码中实现的,你 在任何地方都找不到隐藏的 C 实现。
了解内部结构的最佳来源 编译器(以及如何实现)是GHC Developer Wiki 特别是“GHC 评论”链接。如果您有足够的空闲时间,来自 波特兰 2006 年 GHC 黑客松绝对令人着迷。
请注意,编译器是用它的语言编写的 编译并不少见。许多编译器都是“自托管”的意思 它们是用它们编译的语言编写的,并且旨在 自己编译。例如,参见另一个 Stack 上的这个问题 交换姊妹站:Why are self-hosting compilers considered a rite of passage for new languages?,或者干脆谷歌 “自托管编译器”
正如您所说,这很“棘手”,因为您需要一种方法来获取 过程开始。一些方法是:
您可以使用不同的语言编写第一个编译器 已经有编译器(或用汇编语言编写);然后, 一旦你有一个正在运行的编译器,你可以将它移植到相同的 它编译的语言。根据this Quora answer, 第一个 C 编译器就是这样写的。它是用“NewB”写的 其编译器是用“B”编写的,这是一种自托管编译器, 最初是用汇编编写的,然后用 自己。
如果该语言流行到足以拥有另一个编译器,请编写 编译器用自己的语言分阶段编译,首先 与其他编译器,然后与自身(由 其他编译器),然后再次使用自身(由自身编译)。 最后两个编译器可执行文件可以比较为一种 大量测试编译器是否正确。 Gnu C 编译器可以 以这种方式编译(这当然曾经是从源代码安装它的标准方式,使用供应商的 [劣质!] C 编译器开始)。
如果用另一种语言编写的解释器已经存在或正在 易于编写,编译器可以由解释器运行 编译自己的源代码,然后编译编译器 可以用来自己编译。 The first LISP compiler 是 声称是第一个以这种方式引导自身的编译器。
通常可以通过在语言的受限核心中编写编译器(至少最初是这样)来简化引导过程,即使编译器本身能够编译完整的语言。然后,低于标准的现有编译器或简化的引导编译器或解释器可以启动该过程。
根据the Wikipedia entry for GHC,最初的 GHC 编译器是在 1989 年用 Lazy ML 编写的,然后在同年晚些时候用 Haskell 重写。如今,新版本的 GHC 及其所有闪亮的新功能都是在旧版本的 GHC 上编译的。
Python 解释器的情况有点不同。一个 解释器可以用它解释的语言编写,当然, 在 Lisp 世界里有很多写 Lisp 的例子 Lisp 中的解释器(为了好玩,或开发新的 Lisp 方言,或 因为你是inventing Lisp),但不能都是口译员 一路下来,所以最终你需要一个编译器或一个 用另一种语言实现的解释器。结果,大多数 口译员不是自托管的:主流口译员 Python、Ruby 和 php 是用 C 编写的。(尽管 PyPy 是一个替代 用 Python 编写的 Python 解释器的实现, 所以...)
【讨论】:
GHC 可以使用标志来构建,这些标志告诉它创建非常未优化的 C 程序而不是可执行文件。这就是如今它在新平台上的引导方式。以上是关于GHC 内部结构:类型系统是不是有 C 实现?的主要内容,如果未能解决你的问题,请参考以下文章