The year 2015 starts and I’m working on a code generator, which is one of the more enjoyable tasks in software for me. Code generators and meta programming requires considerably more mental focus than banging out business code, the kind of focus where any interruption is tantamount to dumping the Atlantic Ocean on a continental scale forest fire. It also means the interrupter is subject to an assortment of growls, stares, and verbal assaults, and for these I apologize.
The are a couple specific challenges this project, but the general challenge in building code generation software is in building a model that can serve two masters. On one hand, the model has to make the actual generation phase easier. On the other hand, the model has to be easy to build from some source of data, be it a visual designer or, in my case, XML. Not just any XML, but XML of debilitating complexity as one critic puts it, and I agree. There are times when I suspect someone has willfully obfuscated the XML, but then I remember Hanlon’s razor (with a twist):
Never attribute to malice that which is adequately explained by stupidity, or is the output of a standards committee.
Regardless of the data source, I’ve been to the codegen rodeo before, and the code usually falls into place like the following:
Ah, you must be talking about the complex framework by the name of Angular.
Well, no, but let’s use Angular as an example. It is, truthfully, a simple framework when you discard all the permutations offered and stick to simple, disciplined, and calculated practices. Projects go haywire for any number of reasons, here are three examples I’ve seen in just the last week.
1) Projects that treat Angular modules as CommonJS or AMD modules, in the sense that every little component needs a dedicated module. With Angular this practice only creates more work and bookkeeping for little gain.
2) The confusion between module.factory and module.service. I always try to tell people to think of factory and service as registration APIs only. To the consumer, it doesn’t matter which one you choose, they both create a service component. When people tell me they are passing a factory to their controller, I get confused. The factory API registers a factory function, but the function is not what the injector will pass to a controller, the injector will pass the output of the method, which is the service.
Taking a step back, both of these problems stem from one of the “two hard things”:
There are only two hard things in Computer Science: cache invalidation and naming things.
-- Phil Karlton
And that’s something I won’t escape from. Naming things is hard on the frontend, but also here on the backend, too.