Code generation (in PHP, Java, C#), generates the code of the class library from templates. Custom logic is added in sub-classes or re-opened partial classes.
Benefits/Drawbacks: Code Generation incurs no runtime performance hit, because analysis is during generation & compilation. Compilers can check uses of the generated code and IDEs provide contextual documentation and auto-completion, and debuggers transparently step through the generated code. Code generation templates may also be more general than the limited metaprogramming features e.g. of Python/Ruby. However, the entire library must be re-generated when changing the templates or database schema, which may encourage over-architecting and reluctance to revise the model later, due to the added difficulty of implementing changes (unless planned out so as to support easy/quick re-generation). Also, debugging generated code involves a very slow edit(template)-generate-compile-run cycle, instead of the edit(metacode)-run cycle of metaprogramming.
Source Control: Code templates should be checked in, but it seems also the generated code, because the custom code depends on it, and in Java/C# the generator produces empty classes to hold custom code, which has to be checked in. If pure generated code were not checked in, then code would be a 'pre-build' step, with the drawback of configuring and running the generator locally before the first compile.
I would tend to prefer metaprogramming in most cases, if only because I like small, tidy code. One might imagine that the generated code is not really code to avoid feeling like the code is bloated, since as much as 90% of the total could be generated boilerplate.
Wiki helpfully points out that compilers are code generators (of assembly and machine language), as are interpreters (of bytecode). So everyone uses code generation... the question here is whether to generate code for the language one is typically writing in. Code generation uses a higher level language to output code in a lower-level one, so needing code generators for Java/C# means that in some sense Java/C# are too 'low-level' for certain tasks.
23 December 2008
Code Generation vs Metaprogramming in ActiveRecord patterns
My thoughts on the QCodo article I was reading, along with some Wiki and c2.
ActiveRecord Pattern: "An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data".
Metaprogramming (in Lisp/Scheme, and to a limited extent Python and Ruby) would generate a class library at run-time, for example to perform object-relational mapping with the ActiveRecord pattern. In Python at least, the code is just the metaclass and decorators, and some custom logic added on.
Benefits/Drawbacks: Metaprogramming keeps code small and simple. Meta-changes take place in one piece of code (the metaclass), and database modification is simple, making metaprogramming efficient for rapid prototyping. However, runtime reflection reduces performance (mitigated through caching of the analysis), and since the concrete code does not exist until run-time, there is no static checking of method calls or IDE auto-completion and contextual help for methods. Step-through debugging is complicated for runtime-generated methods compared to concrete methods. Metaprogrammingmay also run into language limitations (not with Lisp macros),necessitating code-generation to produce 'scaffolding' in certain cases(examples anyone?).
Code generation (in PHP, Java, C#), generates the code of the class library from templates. Custom logic is added in sub-classes or re-opened partial classes.
Benefits/Drawbacks: Code Generation incurs no runtime performance hit, because analysis is during generation & compilation. Compilers can check uses of the generated code and IDEs provide contextual documentation and auto-completion, and debuggers transparently step through the generated code. Code generation templates may also be more general than the limited metaprogramming features e.g. of Python/Ruby. However, the entire library must be re-generated when changing the templates or database schema, which may encourage over-architecting and reluctance to revise the model later, due to the added difficulty of implementing changes (unless planned out so as to support easy/quick re-generation). Also, debugging generated code involves a very slow edit(template)-generate-compile-run cycle, instead of the edit(metacode)-run cycle of metaprogramming.
Source Control: Code templates should be checked in, but it seems also the generated code, because the custom code depends on it, and in Java/C# the generator produces empty classes to hold custom code, which has to be checked in. If pure generated code were not checked in, then code would be a 'pre-build' step, with the drawback of configuring and running the generator locally before the first compile.
I would tend to prefer metaprogramming in most cases, if only because I like small, tidy code. One might imagine that the generated code is not really code to avoid feeling like the code is bloated, since as much as 90% of the total could be generated boilerplate.
Wiki helpfully points out that compilers are code generators (of assembly and machine language), as are interpreters (of bytecode). So everyone uses code generation... the question here is whether to generate code for the language one is typically writing in. Code generation uses a higher level language to output code in a lower-level one, so needing code generators for Java/C# means that in some sense Java/C# are too 'low-level' for certain tasks.
Code generation (in PHP, Java, C#), generates the code of the class library from templates. Custom logic is added in sub-classes or re-opened partial classes.
Benefits/Drawbacks: Code Generation incurs no runtime performance hit, because analysis is during generation & compilation. Compilers can check uses of the generated code and IDEs provide contextual documentation and auto-completion, and debuggers transparently step through the generated code. Code generation templates may also be more general than the limited metaprogramming features e.g. of Python/Ruby. However, the entire library must be re-generated when changing the templates or database schema, which may encourage over-architecting and reluctance to revise the model later, due to the added difficulty of implementing changes (unless planned out so as to support easy/quick re-generation). Also, debugging generated code involves a very slow edit(template)-generate-compile-run cycle, instead of the edit(metacode)-run cycle of metaprogramming.
Source Control: Code templates should be checked in, but it seems also the generated code, because the custom code depends on it, and in Java/C# the generator produces empty classes to hold custom code, which has to be checked in. If pure generated code were not checked in, then code would be a 'pre-build' step, with the drawback of configuring and running the generator locally before the first compile.
I would tend to prefer metaprogramming in most cases, if only because I like small, tidy code. One might imagine that the generated code is not really code to avoid feeling like the code is bloated, since as much as 90% of the total could be generated boilerplate.
Wiki helpfully points out that compilers are code generators (of assembly and machine language), as are interpreters (of bytecode). So everyone uses code generation... the question here is whether to generate code for the language one is typically writing in. Code generation uses a higher level language to output code in a lower-level one, so needing code generators for Java/C# means that in some sense Java/C# are too 'low-level' for certain tasks.
0 comments:
Post a Comment