...a bit offtopic, but I was wondering while reading the example of using C itself as the C preprocessor language: why don't languages provide the ability to do this kind of thing automagically, I mean marking some code to be executed at compile time and act as a code generation feature? (I know, it's easy enough to write a small preprocessor that does it, and it's just primitive string based macros, but having a standard way to do it baked into the building tools or the interpreter for an interpreted language seems ...neat ...even cool if some more "magic sauce" would be added to it to make these "macros" hygienic :) ).
> why don't languages provide the ability to do this kind of thing automagically, I mean marking some code to be executed at compile time and act as a code generation feature?
There's certainly already languages that do this type of thing. Haskell has Template Haskell which lets you execute Haskell code at compile time to generate code. I'm pretty sure multiple ML's also have similar meta-programming features.
There is a distinction to be made. In non-homoiconic languages writing macros takes a lot of effort, while in Lisp it's very natural.
On the other hand I don't feel that's an advantage for Lisp, because macros are not composable as functions are and you have to really grok Lisp in order to write macros effectively and also recognize instances where they are appropriate.
I don't think writing Template Haskell macros takes a lot of effort. It is probably harder than Lisp macros, but the main effort is studying the TH API once.