The story of software engineering has been the story of increasing the
level of abstraction at which we as programmers work, from logic encoded
in hardware to toggle switches representing binary digits, through machine
code, assembly language, low-level languages, and high-level languages
both procedural and functional. More recently, we have declarative models
of business processes that can be shared and discussed with folks who
have no formal training in computer science at all. I’d wager that most
readers were nodding along with my list above until I got to the last item.
Has abstract modeling become a proven mainstream technique yet,
accepted and used by all in the industry? No, of course not; this is the
abstraction increase that we’re currently involved in working out, and
doubts and skepticism still abound. It’s hard to remember now, but all earlier
progressions were surrounded by doubt as to their value as well. In the
infancy of each new technique, programmers wanted detailed access to the
previous layer, not fully trusting the new tool to meet their needs, but as
tools and understanding matured, this requirement slipped away. Today,
few developers feel the need to examine the IL or bytecode produced by
their C# or Java compiler, and fewer still the assembly code produced by
the JIT compiler underlying their runtime.
Code generators bridge the gap from nascent abstractions to their well
understood predecessor technologies. They facilitate working on a problem
at a higher, more productive level and translate that to a practical solution
based on best practices at a lower level. Of course, all this talk of raising
abstraction levels implies some sort of grandiose vision of defining your
application with metadata and generating the whole thing. This book
demonstrates clearly that nothing is further from the truth and that starting
small is where the value is at when it comes to code generators.