Rehashing the Boilerplate

I’m about to start a big flash project, so I was looking at Flex. I watched their video demo, and besides obviously leaving out some key steps (such as where the hell that side panel came from—they didn’t make that during the video!), I didn’t really like the RoResque boilerplate approach that they took.

In fact, I don’t like boilerplates at all. It’s against my coding philosophy. Sure, it’s nice not to have to type something that doesn’t need to be there, but if it doesn’t need to be there, why is it there at all? It’s a bunch of garbage the reader needs to muck through.

This bit me the first time I wanted to distribute a Perl module. h2xs gives you a module distribution template, but I didn’t know about h2xs at the time. So I opened up one of Damian’s modules to see what I needed. I opened Makefile.PL and started copying by hand1. I didn’t understand some of it; some of the empty definitions seemed unnecessary, but I obliged and copied anyway. Little did I know that what I copied was almost the exact boilerplate. Why was all that crap there? Why didn’t Makefile.PL look like this?

    use ExtUtils::MakeMaker;
    WriteMakeFile {
        name => 'Parse::RecDescent',

That has all the information you need. “Oh, that’s straightforward” I would think, as opposed to “hmm, what’s this here for, hmm, this seems unnecessary, hmm, this seems unnecesary, hmm, this seems unnecessary”.

Boilerplates are a sad excuse for inheritance. I mean, that’s what it is, isn’t it? “I want everything the same as it was in this other project, except this thing.” But we know that it’s not a good idea to just copy an old project and start modifying it. What if there was a bug in the one you copied; there’s now a bug in the new one! So why are boilerplates any better?

“Well, because they’re small enough that you can verify that all the bugs are out of them.” I doubt that. But let’s suppose that’s true for this paragraph. That’s not the only benefit of inheritance. If you refactored some functionality into a convenience feature to the project you copied, you don’t benefit from it in your new project. If you added support for some slick graphical slide in in one project, you have to re-implement (or copy-paste again, and think of the bugs man, think of the bugs!) in the other.

Needing a boilerplate for a library, be it Flex or Ruby on Rails or whatever, is not a good thing. It’s an indication of a bad library design: a library that makes you specify more than you need to think about. If a project requires loading up a boilerplate and changing one line, the size of this project should be three lines, not the 500 from the boilerplate:

  1. Use the library
  2. What to override
  3. The thing you override it with

You get some benefits this way. First, readers of your code who are familiar with the library can immediately see what your program does without having to read through the whole boilerplate (or diff against the boilerplate). Second, you are free to change anything in the library code and the benefits will filter down into client programs (again, without forcing them to do a diff/patch).

But boilerplates do have their advantages, too. For example, in the library design I just presented, the library designer has to be aware of everything you’ll want to override. Now, that’s sort of a good thing, because the library designer is aware of what his interface is so he knows what will and what won’t break backward compatibility. But this is also sort of a bad thing, because library designers generally suck at deciding that. They think their word is absolute, “you shouldn’t have changed that part, it belongs to me“, when at the end of the day what matters is whether your application got written. If you need to change a configuration timeout that was stored in a source file of the library and not abstraction (see RakNet :-), you’re pretty much boned.

To do a boilerplate in an efficient manner, you have to have excellent version control support. svk can do the job, git probably can too (I actually haven’t looked into it). Basically, your codebase needs to be a branch of the boilerplate’s codebase. This means that when the guy who wrote the boilerplate (even if it’s you) changes something, you can integrate the changes back into your application. Merge conflicts will tell you when you need to rethink how part of your application works because someone rethought how the boilerplate worked.

Using version control like that is like using prototype-based OO on the entire project scale. Prototype OO tends to be high on flexibility and low on abstraction. Which is okay, but when you try to make a project that uses components from two branched projects, you have a lot of work ahead of you.

There really is no process excuse for writing code the right way. You can get some of what you want by using boilerplates and version control, but your code’s reusability will eventually suffer. At some point, you have to be a mathematician: you have to think about the essential algebra of your program and factor that into a core, and program the fluff functionality as plugins. Not soft-coding: keep general extensions in a Turing-complete language. But there is no substitute for good ol’ modular, well-thought-out design2.

Preachy rants for everyone!

1I never use copy/paste when I’m programming. In this case it means that I have to read what I’m putting in my code base, so I can start to understand it instead of just relying on “it works, leave it be”. In cases where I know what I’m doing, it forces me to refactor and abstract because I get tired of typing.

2Please note that I did not say object-oriented. Object oriented design is a great methodology to achieve modularity most of the time. But being object oriented neither implies being modular nor vice versa.


5 thoughts on “Rehashing the Boilerplate

  1. Great quote: “Using version control like that is like using prototype-based OO on the entire project scale.”

    I’d love to see somebody turn that simile into a formal equivalence.

    Turning it around, what is the version control equivalent of powerful static typing with inference? It would help the programmer make and manage semantically valid changes. I’d like to have one of those to manage my code base!

  2. That’s a nice idea – that about the version control. Personally I don’t thing this boilerplate thing is that bad – while I mostly agree with all your points I believe that abstraction is sometimes just too hard – and it is much more important to have something working (I mean a framework that works as a base for projects) than something correct. ‘Worse is Better’.

  3. Hi Luke. If you don’t like the RoR way, what would you recommend (in the Perl world)? Unfortunately, most frameworks now are based/inspired too much by Rails…

  4. David, you’re talking about specific modules? Because even though this was a ranty post, I thought I presented my philosophical alternative: good ol’ modular, well-thought out design. POE is a pretty good example of that. Think about how POE could have been a boilerplate instead. Say it were a very featureful threadless http server boilerplate instead of a suite of modules. Do you think it’s very likely that POE would end up being used for things that weren’t servers of some form? Probably not. Do you think it would be easy for people other than Rocco Caputo to publish their extensions of POE in general? Probably not.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s