Sidenote, just learned about Haxe which may offer some insight into this question.
The basis of my question is what sorts of tradeoffs (if any) need to or must be made if you wanted to compile one language into several others. I am in particular thinking like this in terms of plugins, but you could also apply it to cross-language compilers.
Basically, for compilers, the goal is to write some code in say JavaScript or perhaps TypeScript, and then compile it to different native platforms/languages/environments like in C, Java, Swift, etc. A middle ground seems to be with plugins for say WordPress, Magento, Shopify, etc.. You might have a simplified template language you are using, or may opt for PHP or some other language as your "primary" language, and then while not compiling to different languages, you are compiling to different lets say "pages" or "template" styles in each platform. On the more extreme end that still seems related is how like with the Fog library in Ruby, they abstract away AWS, Google Cloud, Azure, etc. into a single higher-level abstraction, and you can target any one of these services as a backend. Maybe somewhat similar to that is Homebrew, but not too sure about that.
What I'm mainly wondering is if it's possible to write a generic abstraction layer and have it compile to multiple different targets in these cases and others like it. I know for example Linux abstracts away different architectures so you don't need to write your code specific to an architecture most of the time (all of the time?), but I don't know of a "Higher-Order Operating System Layer" that abstracts all operating systems like Linux, Mac, and Windows, into one thing, so that you can use any of them without regard to the underlying implementation. (Why didn't they do that?)
But basically, can you write a compiler that takes a source algorithm and transforms it into a target language algorithm in a generic way? Say for example, graphics rendering, or http servers. With graphics rendering I know of Metal on the Mac/iOS, WebGL in the browser, the DOM in the browser too, OpenGL on Linux, DirectX on Windows perhaps (I'm reaching, don't know for sure). I can sort of imagine having a generic "graphics" layer that has the concept of sprites and pixels and colors and whatnot, and then it compiling to each of these target platforms in an optimized way. But is this a fantasy? Must you write the algorithm for each particular platform individually? That is, say you write a physics engine in some hypothetical "Higher-Order Graphics Layer". Can it then compile your higher-order physics engine algorithms and data structures down into several totally different target platforms/languages?
What tradeoffs must be made? What limitations are there? Is it even possible? If so, what measures must you take to implement something like that?
For an HTTP server, let's say you just have a simple algorithm like "open socket, loop to listen for connections, etc.". Well, in JavaScript you don't even need to do this, you can just do httpServer.listen()
. But in C you might need to allocate some memory and do some stuff in addition to opening sockets and such. So in this case it seems hard (but I don't know, is it impossible or practically infeasible?) to write a generic algorithm for an HTTP server in both C and JavaScript. Is it though? Is there a way to -- I don't know, using some Gang of Four design patterns or something like that -- to write an algorithm for an HTTP server that worked on both platforms (and others)? Or for the game example, same thing?
In the extreme you would just say make game engine
and it would make the best game engine for each platform. But short of that, let's say you write a game engine in some higher-order way. Is it even remotely possible to make it compile to several target platforms without rewriting the whole thing from scratch for each platform?
Basically all of these examples hint at the main question: is it even possible to build a transformation of one system into several others in a programming sense? I don't even know if this is an area of research which might have research papers which could help better understand the problems in this area. But either way, I'd like to know if it's possible, and what the tradeoffs are or what you generally have to look out for.
LLVM seems related, but the low-levelness and well-definedness of assembly seems to make the problem a lot easier to solve. I'm not sure if it's possible in the situations I've described here (and others).