This is a somewhat old post, but I'm not reading this forum as often as I'd like anymore, and I feel like I have to comment.
Solar wrote:
Not so sure about two points: code generating code, and Makefile replacements. If there is any chance you might take help onboard or pass the project to some other maintainer later on, both add complexity and "required knowledge" making it more difficult to understand your code.
Code generating code is a "Good Thing" as long as nobody ever needs to touch the generated code, other than possibly code generator debugging reasons, kinds like you sometimes read assembly code that your C compiler wrote out to see what went wrong (or more often run a debugger).
The important point though is that code generation is good idea if and only if the code generator is more simple than the generated code. A compiler is a good thing, because writing compiler is more simple than writing everything in assembly, and an assembler is a good thing, because writing things in assembly (or writing a compiler generating assembly) is more simple than writing everything in machine code.
Going to the other direction, code generator is a good thing, when your problem is such that it's algorithmically relatively easy to transform it into some existing language (say C) but the problem is complicated enough that writing it directly in C would result in an unreadable mess, and be impossible to debug.
A lot of common problems in programming could be avoided by generating more code. I personally do a lot a programming in Python or Ruby, which simply transforms some domain specific language into some more standard language, or writes highly repetitive source code or header for me. And I'd like to do this even more. I used to think this just adds complexity, but it really does reduce it most of the time.