Code Generation in Action
Overview Code Generation in Action, CGiA to its friends, is presented in two parts. The first part is four chapters, and covers a code generation case-study, the basic principles of code generation, including the different types of code generation strategies together with reasons why you would or would not use each strategy. The book's chosen toolset for building generators is presented next, and then some walk-through examples of building simple generators wraps up the first part.
The second part is a kind of a cross between a cookbook and a list of engineering solutions. There are nine chapters with the breadth of solutions covered being quite impressive, covering the gamut of generation of user interfaces, documentation, unit tests and data access code. Each chapter presents a couple of solutions within its topic area, often for different technologies within that topic. For example, the user interface chapter covers the generation of Java ServerPages, Swing dialog boxes and then Microsoft MFC dialog boxes. No favouritism here!
What's To Like There's a lot to like with this book. The writing is very clear and of good prose. I found the introduction to be very compelling, and I felt completely drawn in by the opening case-study. The four chapters of part one are a concise case for code generation, and would be very useful information to help persuade co-workers and management of the positive risk/benefit ratio with trying code-generation on a live project.It would be impossible to try enough of any solution from part two in a time-frame short enough to make this review useful, but in the solutions that match my areas of knowledge, I found myself admiring Herrington's straight-forward and pragmatic approach.
What's To Consider There are two aspects of this book that I want to flag. One of these aspects, some will love and others will hate, and that is the choice of generator language for CGiA. The author has chosen to use Ruby as his working language. This is an interesting choice. Ruby is certainly a language that is inspiring a lot of admiration these days (in fact, it's hard to get Dave Thomas to stop talking about it :-), but with the majority of the code-generation examples being for Java-related technologies, I wonder why Java was not selected instead.I also found myself wondering about the lack of discussion of how to integrate these Ruby tools into a typical Java build process. Many developers I know use ant to bring automation and consistency to their builds, yet the book doesn't mention this. (JRuby anyone?) Certainly something to consider for the second edition or future code-generation authors.
SummaryThis is a masterful tome that inspires and delights, although the two issues raised above did cost it a perfect score of ten.
Table Of Contents- Code generation fundamentals
- Overview
- Code generation basics
- Code generation tools
- Building simple generators
- Code generation solutions
- Generating user interfaces
- Generating documentation
- Generating unit tests
- Embedding SQL with generators
- Handling data
- Creating database access generators
- Generating web services layers
- Generating business logic
- More generator ideas
You can purchase Code Generation in Action from bn.com. Slashdot welcomes readers' book reviews -- to see your own review here, read the book review guidelines, then visit the submission page.
if you ever read the "Pragmatic Programmer" book about software developer practices, it mentions that they used code generation for many things. Code generation definitely helps when you have many similar but not same implementation.. But, in Java or any other object oriented languages, inheritence can be used to avoid similar looking code (which is what code generation would do).
But, even here, I think the UI pages, or template based generators definitely help. There was a tool by DevelopMentor which used to generate code for ATL. It was based on templates..
The author has chosen to use Ruby as his working language. This is an interesting choice. Ruby is certainly a language that is inspiring a lot of admiration these days..., but with the majority of the code-generation examples being for Java-related technologies, I wonder why Java was not selected instead.
I think the author makes it pretty clear why he chose Ruby instead of Java. Essentially, in order to parse text (which is one of the primary functions in code generators) you would have to write 2 to 3X more code in Java than you would in Ruby. Java is not an optimal text parsing language - first off you have to find a regex engine for it. That leaves you with choosing one of the scripting languages: Ruby, Perl or Python.
Here's what the author says about the cons of using Java for code generation (page 41):
* Java is not ideal for text parsing. (I would agree)
* Strong typing is not ideal for text processing application (again, I would tend to agree, strong typing only gets in your way)
* The implementation overhead is large for small generators. (you'll be writing a lot more java code than you would in Ruby to get the same thing done)
Overall, I'm finding it to be a great book, and the use of Ruby for implementing the examples is a plus as far as I'm concerned.
As far as integrating Ruby into the build process goes, I recall hearing something about a project that uses Ruby to drive Ant.
Actually, it's very much there. It's not a _replacement_ for development, but there are many parts of coding which is benefitted by code generation. I often write tools to write code for me. Once I had to write a color-picker in HTML (VERY repetitive code), so I wrote a code-generator in Emacs Lisp and it saved me several hours. Several implementations of this concept exist:
* Templating (see Alexandrescu's book on Modern C++ design)
* Macros for those in the Scheme/Lisp world (these are GREAT and AWESOME)
* Compile-time programming (only available in LISP as far as I'm aware through the eval-when construct)
* Custom program-generators
And then there's the related concept of partial evaluation that, while excellent, has received very little attention by the commercial sector.
Now, many code-generation facilities could be done better with good libraries, but this isn't universally the case. Delphi is probably the best at putting in libraries/properties what others put in code generators, and their software is much easier and better because of it.
Macros and compile-time programming are two of the best ways to do this, but Scheme and LISP are the only ones that do this reasonably.
Engineering and the Ultimate
For those who are saying that the term "Code Generator" isn't applicable - it is. Consider a C++ compiler. It may generate asm code, which then gets converted into machine code.
(generic) C++ -> (specific) asm -> executable bits
(obviuosly, the C/C++ compiler doesn't need to generate asm, but it's still code generation if it does)
Code generators just take this a level higher, so the code "life cycle" looks like this:
(generic) Diagram / CG description -> (specific implementation) C++ -> (specific machine) asm -> machine code.
Code generators have a great potential for easing coding and documentation. Just like GCC has many backends to generate code for different processor architectures, the code compilers can have different backends to make source code in different languages (C, C++, Fortran, whatever). Even better, you can run a different translator and get documentation out of the "source" - in HTML, DocBook, XML, or any other format you want.
There are tools to let you make UML diagrams (Google for "Executable UML" for great goodness), and generate real-time C code for an application, a C++ app simulator that runs on a PC, and documentation for the system, all from the same diagram. The tools are expensive (like $15k-$30k), but for large projects, they can be a great savings.
I saw a program called BridgePoint (from Project Technologies), which was able to generate embedded, real-time code that was as efficient (more in some areas, less in others, but it averaged out the same) as hand-optimized code done by expert programmers. It all depends on how goo dyour translator is (and this program lets you write your own).
Some books on the subject:
"Executable UML: A Foundation for Model-Driven Architecture", by Stephen J. Mellor and Marc J. Balcer
"Executable UML: The Models are the Code", by Leon Starr
"Real-Time UML: Developing Efficient Objects for Embedded Systems, Second Edition", by Bruce Powel Douglass
- The Sigless Wonder
Yes, of course you can do this in lisp.
The point your parent poster was making, is that a lisp program has the full power of the language available at macro expansion time, just prior to compilation. This means you can redefine the syntax of the language at will to create any language you like on top of lisp. Lisp macros should not be confused with c-style macros, which are merely token substitutions, not redefinitions of language grammar.
You only have this in perl in a very crude and hackish sense. You have to write your own parser; you have to write your own code generator; you have to run every piece of code through your home-brew parser/code-generator before you send it to the perl interpreter. Debugging? Heaven help you if any of:
1. Your code written in your new-language-built-on-perl has errors
2. Your parser has errors.
3. Your code generator has errors.
In Lisp, the macro facilities come for free, are part of the standard (so macros are portable). Vendors are responsible for correctness, so debugging is a simple matter of using the built in functions macroexpand and macroexpand-1.
Saying that Perl has the same sort of code generation capabilities as Lisp is rather like saying that, since all languages are Turing equivalent, assembly language has the same macro capabilities as lisp.
The power of a language comes from its expressiveness, the things it lets you do easily without having to resort the 21st century equivalents of a turing machine. With Perl, you only get this level of expressiveness by using convoluted, error prone, home-brew substitutes for real macros.