How are Haskell programs compiled and executed internally?

David picture David · Sep 13, 2012 · Viewed 8.8k times · Source

I'm having trouble understanding how Haskell (GHC) compiles programs, and how those programs are run.

  1. GHC is the canonical example of a nontrivial program written in Haskell. However, parts of GHC seem not to be written in Haskell, namely the runtime environment (in C/C--). Why is that? Performance reasons? (I am aware of this site and its friends, but cannot make much sense of them.)
  2. Speaking of the runtime environment: Why does a compiled language need one? Shouldn't the compiled program be machine code and nothing else? From what I understand, a runtime environment is somewhat similar to a virtual machine or a bytecode interpreter, that deals with some form of meta code and does the actual calculations based on that. So: what does the GHC runtime do exactly, and why is it necessary in the first place?
  3. Concerning the FFI: How are C calls handled? Initially, I thought using the FFI generates a single executable where Haskell and C are compiled together. However, I read multiple times that GHC programs kind of do a call out of the program to the C function. This is especially relevant to understand the problem the FFI has with parallel programming. So: how are FFI functions different from normal Haskell functions?

Answer

Don Stewart picture Don Stewart · Sep 14, 2012

To compile and execute a programming language on stock hardware you need a number of things:

  • a compiler to translate your source language into assembly code executable by the native host
  • a support library (aka runtime) for primitive language services, such as memory management, IO and thread management. Things that must be leveraged from lower-level system services.

C, Java, and GHC Haskell are examples of such systems. In the case of GHC, the entire architecture is described here. The pieces are also described individually, and in detail.