The motivation behind "generating Java" was that the game could then be deployed in a browser, just like Minecraft is. Maybe Clojure can already do that though. I haven't looked yet. =)
Clojure runs on the JVM, but perhaps Clojure is expensive in the context of a 60-frame-per-second realtime app. I doubt it would be significantly more expensive than Java, but that's something to test.
So by generating Java, then it would be an interesting system because it winds up producing the same sort of code which Notch made by hand to deploy Minecraft to a browser. Yet it's derived "from the clojure code".
And yet it's also generating C code, which is also derived "from the clojure code". So it's very meta, which I can't resist exploring.
Why is it "pretty much impossible" generate the game engine C code in a non-lisp language?
Well, it's straightforward for you write a program which generates some C code. But how about "either C, or Java"? Or "either C, or Java, or Haskell", ... etc.
You'll soon discover that the nature of the implementation is completely different for different languages. A Haskell game engine would look utterly nothing like a C implementation would look.
So the situation is, you would need an intermediate source code representation of your game engine which supports introspection. And whatever data structure you use must also be able to be modified during the "code generation", because it's not until the codegen step that you know what sort of special-casing you'll have to do (in order to generate code which implements your game engine in e.g. haskell, or brainfuck, or... etc. Point being: each of those has a different set of special-case requirements, and you can't know which until you're already in the codegen phase.)
So, you could use a different language, and you could represent your "game engine source code" as, say, JSON. And you could have conventions for what your various operations "within that JSON string" actually mean -- e.g. whether you use infix notation, or prefix notation, or.. etc.
And then you could have a notation for how to specify a function, within that JSON string.
And so on.
But then, at the end of it all, you wind up with a poorly implemented version of what lisp already offers you. It lets you do all of that automatically, because those features are built right in to the language. Indeed, the language is the primary reason the features are possible: Everything is a list, and everything has access to all lists at all phases of the program's lifespan. You can run at compile time, or compile at run time, etc. You have access to the entire syntax tree at all times, in every program you write, which enables you to manipulate it. You simply can't do that with e.g. Python. Hence the requirement for an "intermediate thing, which you can manipulate" -- we happened to decide on using JSON as the representation, but you could've easily decided to use something else, etc. The point is, that "intermediate representation" is just a poorly-reimplemented version of the toolset which Lisp gives you by default.
I wonder if Python's metaclasses would get you what you're describing. Some thought would have to go into the primitives required to generate the constructs for the destination language(s), but metaclasses would allow you to serialize to different languages fairly easily once the primitives are in place. This approach isn't nearly as elegant as Lisp, but I think it takes what you're describing out of the "pretty much impossible" realm.
Overall though I agree with you, I just had a slight disagreement with the "pretty much impossible" claim.
I just had a slight disagreement with the "pretty much impossible" claim.
Thanks for pointing that out. Being a scientist, I too would take issue with this :) hence, I'm extremely interested in discovering whether this would be a workable, real-world solition for the problem I described.
I'm out of time right now, but would you mind emailing me? (Address is on my profile page.) I'd really love to get your thoughts about a couple followup questions that I have.
Why is it "pretty much impossible" generate the game engine C code in a non-lisp language? What is it about Lisp that makes it possible?