Implementing a JIT Compiled Language with Haskell and LLVM
stephendiehl.com
stephendiehl.com
That's like asking on a cooking forum how to open a coconut, and the reply being well any physical object with mass can technically open a coconut with the correct application of force, but yeah, you should probably use a machete.
So while the "any Turing complete language" is an over-generalization, so is "use the right tool for the job". Programming languages are not at all like knives or hammers as they are 1/ terribly expensive 2/ require constant training 3/ require specialization and 4/ each designed to be general-purpose. It's more productive to use just one language you know best than keep switching to a completely different one that's marginally better at the particular task at hand.
There are other great features for compiler development in the ML family, but almost all of them revolve around static types.
Can you explain what you mean when you say Lisp is excellent for compiler development? When changing the AST, how would you go about changing all the code that needs to be changed?
See a couple of examples of this:
Is there an answer to this question?
I think the best classification of programs was given by Gérard Berry[1], creator of Esterel, a very influential imperative, fully verifiable language for reactive systems[2]:
Computerized systems can be divided into three broad categories:
* Transformational systems compute output values from input values, and then stop. Most numerical computation programs, payroll programs, and compilers are transformational.
* Interactive systems constantly interact with their environment in such a way that the computers can be viewed as the masters of the interaction. A user calls for services, the system listens to him when it can, and it delivers the services when they are available. Operating systems, centralized or distributed databases, and the Internet are interactive.
* Reactive systems, also called reflex systems, continuously react to stimuli coming from their environment by sending back other stimuli. Contrarily to interactive systems, reactive systems are purely input-driven and they must react at a pace that is dictated by the environment. Process controllers or signal processors are typical reactive systems.
In another paper (The Foundations of Esterel) he expounds:
* In interactive systems... [t]he computer (network) is the leader of the interaction, and clients wait to be served. The main concerns are deadlock avoidance, fairness, and coherence of distributed information.
In reactive systems, the pace of the interaction is determined by the environment, not the computers. Most often, clients cannot wait. The main concern are correctness (safety) and timeliness.
[1]: http://en.wikipedia.org/wiki/G%C3%A9rard_Berry
[2]: http://home.ku.edu.tr/~stasiran/ecoe560/Papers/EsterelPrimer...
My background is linguistics, so perhaps I'm biased to see everything as a compiler. However, automata theory generally provides a similar perspective.
It is because the problems and algorithms involved are completely different. An optimizer might address some of those problems in the generated code; it may be a solver for some of those problems (e.g. register allocation, which is one kind of a scheduling -- i.e. resource allocation -- problem), but it is not itself a solution to scheduling and coherence problems.
As evidence, I'd offer the fact that the verification of online programs requires temporal logic (which is strictly more powerful than, say, session types) -- Esterel itself is based on temporal logic, and TLA+ uses temporal logic to verify algorithms used in online programs -- while, AFAIK, no temporal logic is required to verify a compiler. That their verification requires different logic shows that they solve a qualitatively different problem.
However, some of the most interesting and important issues are left out of it. Some examples are implementing exceptions, threading, imports, garbage collection, closures , etc.. I would love a more advanced version of this article that discusses how to implement a more advanced compiler with more modern features (specifically in LLVM).
[0] github.com/xldenis/mgc