我无法理解Haskell(GHC)如何编译程序,以及这些程序是如何运行的。
答案 0 :(得分:28)
要在库存硬件上编译和执行编程语言,您需要做很多事情:
C,Java和GHC Haskell就是这种系统的例子。在GHC的情况下,entire architecture is described here。这些作品也将单独描述并详细描述。
运行时服务(又名“GHC运行时”)在几篇论文中有所描述:
答案 1 :(得分:13)
我可以提供运行时的精确度。
虚拟机是“一种”运行时,但不是唯一的运行时。运行时系统只是程序在执行期间可以假设的环境(以及服务集)。即使像C和C ++这样的非常低级的语言也有运行时系统(想想malloc ......某人/某事正在为你做分配,甚至是零检查)。
通常,更高级别的语言具有更丰富的运行时(意味着运行时为执行程序提供更多服务);那些范围从内存管理(例如垃圾收集)到反射/内省基础设施(想想ruby等......)到数组边界检查,但几乎所有语言都有某种运行时系统(如果只是操作系统)。
答案 2 :(得分:8)
1:为什么RTS不是用Haskell编写的?
因为它会执行无法在Haskell中表达的低级别的东西。很像Linux内核是一个运行C程序的系统,但Linux内核的部分内容是用汇编语言编写的,而不是C语言。
2:为什么编译的程序需要运行时环境?据我所知,这就像Java字节码解释器。
GHCi使用几乎与Java字节码解释器完全相同的东西。 编译 GHC程序没有;编译后的程序是原始机器代码。
相反,Haskell RTS更像是一种迷你操作系统。它做内存管理,它做线程调度,它做异常处理的某些方面,它做事务处理。每个Haskell程序都在这个迷你操作系统下运行。(有点像C程序编译,它是原始机器代码,但如果没有像Windows这样的操作系统,你仍然无法运行它Linux或其他东西。)
例如,每次Haskell程序内存不足时,Haskell程序就会停止运行,垃圾收集器会开始运行。垃圾收集器试图释放一些内存,一旦它有了,Haskell程序就会重新开始运行。
每个编译好的Haskell程序都有一个这个垃圾收集器程序的副本,它只是Haskell RTS的一部分。类似地,多个Haskell线程可以在一个OS线程内运行,因此RTS内部有一个线程调度程序。我可以继续......
3:FFI是如何处理的?我认为这些东西都是一起编译的。
全部编译[或者更确切地说,链接]在一起。如果编写C程序,一个C函数可以调用另一个C函数。当Haskell调用C函数时,它就像调用C函数的任何其他函数一样。根据函数调用的作用,Haskell方面会发生一些事情,这可能会增加一些开销。