I'm having trouble understanding how Haskell (GHC) compiles programs, and how those programs are run.
- 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.)
- 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?
- 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?