Haskell程序是如何在内部编译和执行的?

40

我对Haskell(GHC)如何编译程序以及如何运行这些程序感到困惑。

  1. GHC是Haskell中非常重要的一个程序示例。然而,GHC的部分内容似乎并不是用Haskell编写的,即运行时环境(用C/C--编写)。这是为什么?出于性能方面的考虑吗?(我知道这个网站和相关信息,但不能理解太多。)
  2. 说到运行时环境:为什么一个“编译语言”需要它?编译后的程序不应该只是机器码吗?据我所知,运行时环境有点像虚拟机或字节码解释器,处理某种形式的元代码,并根据其进行实际计算。因此:GHC运行时环境确切地做了什么,为什么它首先是必需的?
  3. 关于FFI:如何处理C调用?最初,我认为使用FFI会生成一个包含Haskell和C编译在一起的单个可执行文件。然而,我读过多次,GHC程序似乎从程序中调用了C函数。这对于理解FFI在并行编程方面存在的问题尤为重要。那么:FFI函数与普通的Haskell函数有何不同?

14
说到C语言,它甚至使用了一个运行时环境(http://en.wikipedia.org/wiki/Crt0),而这个运行时环境通常并不是用C语言编写的。 - C. A. McCann
1
那么,GHC运行时究竟是做什么的,为什么它第一次出现就是必要的呢?例如内存管理和线程调度。 - Daniel Fischer
4
@C.A.McCann提供的链接指的是“运行时库”,这与“运行时环境”不是同一概念。C/C++运行时库与像Java这样的典型运行时环境完全不同。 - Ken White
1
@David 因为 Haskell 内部并没有处理内存管理的设施,所以它允许你在一个抽象层面上使用类型化的值进行编程,而不是更低层次的操作。 - Kristopher Micinski
1
@C.A.McCann:Java是对“运行时环境”通常和习惯性使用的一个参考。我认为我写的很清楚了。 - Ken White
显示剩余2条评论
3个回答

38

要在普通硬件上编译和执行编程语言,您需要以下几个东西:

  • 编译器将源语言转换为原生主机可执行的汇编代码
  • 支持库(也称为运行时)提供基本语言服务,例如内存管理、IO和线程管理。必须从较低级别的系统服务中利用这些功能。

C、Java和GHC Haskell是此类系统的示例。在GHC的情况下,整个架构在此处描述。这些部分也被单独详细描述。


15
我可以解释一下运行时(runtime)的含义。
虚拟机是“一种”运行时,但不是唯一的。运行时系统就是程序在执行期间可以假定存在的环境和服务的集合。即使是像C和C ++这样的低级语言也有运行时系统(考虑一下malloc...有人/某物正在为你分配内存,或者甚至是除零检查)。
通常,高级语言具有更丰富的运行时(意味着运行时为执行程序提供了更多的服务),这些服务范围从内存管理(例如垃圾回收)到反射/内省基础设施(例如ruby等)到数组边界检查,但几乎所有语言都具有某种形式的运行时系统(如果仅仅是操作系统)。

11

1: 为什么Haskell不用于编写RTS?

因为RTS涉及到一些无法用Haskell表达的低级操作,就像Linux内核是用C语言编写来运行C程序一样,但Linux内核的某些部分是用汇编语言编写的,而不是C语言。

2: 编译后的程序为什么需要运行时环境?根据我的理解,这类似于Java字节码解释器。

GHCi使用的东西几乎和Java字节码解释器一模一样。但编译后的GHC程序并不需要;编译后的程序是原始机器代码。

相反,Haskell RTS更像是一种迷你操作系统。它进行内存管理、线程调度、某些异常处理方面和事务处理等。每个Haskell程序都在这个迷你操作系统下运行。

(这有点像虽然C程序是编译过的,但它是原始的机器代码,但你仍然不能在没有Windows或Linux等操作系统的情况下运行它。)

例如,每次Haskell程序耗尽内存时,该程序就停止运行,垃圾回收器开始运行。垃圾回收器尝试释放一些内存,一旦释放了,Haskell程序就会再次运行。

每个编译的Haskell程序都有一个垃圾回收器程序的副本,它只是Haskell RTS的一部分。类似地,多个Haskell线程可以在一个操作系统线程中运行,因此RTS内置了线程调度程序。我可以继续下去……

3: FFI如何处理?我认为这些东西都是编译在一起的。

它们确实都是被编译(或链接)在一起的。如果你编写一个C程序,一个C函数可以调用另一个C函数。当Haskell调用C函数时,它几乎就像任何其他函数调用该C函数一样。但根据函数调用所做的事情不同,可能会有一些在Haskell端发生的事情,这可能会增加一些开销。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接