If we had a universal interpreter for all available features of programming languages we could use a specializer to generate compilers for all languages. We could simply use any language as source (or input) and any platform as target (output).
We could all write in our favorite programming language to add features to that universal interpreter because the base Abstract Syntax Tree (used by the universal interpreter) could be a target of our favorite programming language. On top of that, you could view the ‘source code’ of the universal interpreter in any language because the ‘source code’ of that universal interpreter is actually an AST.
Despite programmers having these sort of ideas for more than 40 years most of us still seem to think that we need to choose a specific textual representation and appropriate interpreter (or specialized interpreter called compiler).
I don’t get why that is. There are so much programmers around and most programmers are really passionate about their ability to create. I don’t understand why we fight about different programming languages, to me they seem like a different view on the same AST.
Why are we all not using the same base as a library from which we can pick language features?
12
You seem to think that programming languages differ only in their syntax. This is not the case. Languages can have vastly incompatible semantics as well. For example:
- A functional language that uses lazy evaluation and an imperative language that allows side effects are difficult to combine.
- A language that allows pointer arithmetic and a language that guarantees memory safety are difficult to reconcile.
- A program involving infinite loops cannot necessarily be expressed in a language such as Coq.
- A language that allows dynamic dispatch (i.e. OOP) is incompatible with a language that is completely statically typed.
- Some languages don’t offer dynamic memory allocation.
- A program using closures does not have a straightforward representation in a language without garbage collection.
The list of incompatibilities goes on and on.
There are a couple of program representations that are common for different languages. These are called machine code or byte code. While they are functionally equivalent to the original program, most of the structure of the program is lost.
The .NET common language runtime is an interesting example of an intermediate-level language platform that supports a variety of different languages, both imperative and object-oriented (e.g. C#) and functional (e.g. F#). While programs cannot be transformed from one language to the other – slight feature mismatches exist –, different parts of the same project can be written using different languages. Due to the common feature-rich runtime, their interop facilities are practically effortless.
3