To me, boilerplate code is obviously bad. However I've met a developer who displays resistance in any attempt to reduce boilerplate. I realized I didn't have a readily formed, well thought out argument past the abhorrence I have developed for it over time.

So that I can form a convincing argument for favoring less boilerplate, what are some counterarguments? In other words what are the arguments (if any) in favor of boilerplate?

(I mean what I think is generally meant by boilerplate, but a good example is getters and setters in Java.)

@Oded: That is right. But you misread the question. :) He is attempting to look if there is anything to say for boilerplate code. My guess is he is very well informed about the disadvantages.
–
Steven JeurisMay 14 '12 at 19:06

3

@StevenJeuris - I read the question perfectly. Which is why I didn't post an answer. I am only adding to the other side of the argument. Just so the OP has "a readily formed, well thought out argument past the abhorrence I have developed for it over time" for next time ;)
–
Oded♦May 14 '12 at 19:06

7 Answers
7

One important thing to remember is that code is generally made smaller by removing unnecessary context. If the compiler can figure something out, the argument goes, there's no need to write it out explicitly.

What may look like boring, repetitive boilerplate to you as you're writing it can be valuable context to someone else who comes along a year (or five) later and has to maintain your code.

WRT the Java example specifically, I'll agree that that's a good example of bad boilerplate, since it can be replaced by something that's both shorter and easier to read, and also more flexible: Properties. But that doesn't mean that all boilerplate syntactic elements from all languages are as wasteful as the getters and setters from Java and C++.

Of course, this argument works both ways. A considerable amount of boilerplate code is just there to appease the compiler and does not help humans comprehend -- to stay with getters/setters, those dozens lines have to be read entirely to be sure "those are just do-nothing getters and setters", rather than reading a single short line per property which simply states that it's a property and what type it has.
–
delnanMay 14 '12 at 19:19

@Delnan: Agreed. That's what I meant by the last line of my answer.
–
Mason WheelerMay 14 '12 at 20:50

4

I think boilerplate is harmful for the human reader as well. By being forced write repetitive, meaningless text, we are obscuring the relevant parts of the code from other people. If something is helpful, then by definition it's not boilerplate.
–
Andres F.May 15 '12 at 3:09

"... one of the hardest of all languages for ordinary human beings to read, due in large part to its excessive terseness.": This is just your opinion and it is stated as a fact.
–
GiorgioDec 4 '14 at 23:55

@Giorgio: On the contrary, it's much more than just my opinion; it's the opinion of the vast majority of people who have ever tried to study it. And when "difficult to read" is inherently a matter of opinion in the first place, the fact that that opinion is so widely shared pretty much makes it a fact.
–
Mason WheelerDec 5 '14 at 1:04

One argument in favour of boilerplate code is that if you change it in one place, it only affects one flow of the code. This has to be balanced against the fact that more-often-than-not, you actually want a change to affect every piece of code that uses it. But I have seen rare examples that support the argument.

Suddenly your code is becoming less boilerplate. Perhaps you should have accepted the repeated two lines of code. By now you would have three pieces of code, each 2-3 lines long and not looking very repeated any more.

All this said, I would counter that with "this is not a common case, and when it happens, you can refactor."

Another argument I have recently heard is that boilerplate code can sometimes help you navigate code. The example we were discussing was where we'd removed tons of boilerplate mapping code and replaced it with AutoMapper. Now, it was argued, because everything is convention-based, you cannot say "Where is this property set," to the IDE and expect it to know.

I've seen people argue similar things about IoC containers.

Not to say that I agree with them, but it's a fair argument nonetheless.

What is the problem? This is great in order to learn new stuff, and explore alternative solutions, but it's probably not the best commercial decision.

The WPF framework is well documented. It properly documents how to write your boilerplate code. Attempting to remove this boilerplate code is a nice exercise, and something which is definitely worth exploring, but achieving the same level of 'polish' as msdn offers takes a long time, which we don't always have.

However, I'm still quite happy with the result I have at the moment, and gladly use it in my spare time projects. :)
–
Steven JeurisMay 14 '12 at 19:37

3

every time I touch WPF and those dependency properties, I always end up wishing C# had something as simple as C++'s macros. Sure macros are abused in wrong hands, but they could eliminate soooo much repetition here. I'll have to take a look at your AOP framework next time I start wishing for those macros :)
–
DXMMay 14 '12 at 19:46

@DXM If you do, and it crashes miserably, don't forget to blame me and post the errors. ;p
–
Steven JeurisMay 14 '12 at 19:48

Code snippet worked for me pretty well for dependency properties.
–
CodismMay 14 '12 at 19:56

In defense of boilerplate

I have a hard time putting this into words because it's really something I've been noticing just recently, so I'll make a list:

It seems to me that there is a certain fear of having duplicate lines that stretch out a bit. If it's just a few lines it might be no problem at all. some things are inherently "almost repetitive" (like the example above). I see little chance in optimizing there in the long run.

People love to encapsulate functionality somewhere; if you look at objectively and it seems like it's just "hiding the mess" -- be suspicious! it might be the time for some good old boilerplate

When you have a function that becomes more and more powerful; that takes many different execution paths depending on the input and ultimately does very little -- it might be boilerplate time!

When you add a layer of abstraction on top of another layer of abstraction, but just to make your code shorter (the underlying layer is not meant to be changed) -- boilerplate time!

When you have a function that takes so many parameters that you really need to have named parameters -- maybe it's boilerplate time.

One thing I recently always ask myself is this:
Can I copy&paste into another project without changing anything? if yes, it's okay to encapsulate or put into a library, if no: it's boilerplate time.

This is very much opposed to the general perception that boilerplate is copy&paste code. To me boilerplate is about copy&pasting, but always having to tweak it a tiny bit.

The function gets more parameters and has increasingly complex
internal logic to control its behavior in different cases. Too DRY
functions are easy to spot. They have lots of intricate if-then logic
that try to address a wide diversity of usage. [...] Also, repeating
code isn’t always a bad thing if the code is small and performs a
discrete function.

"When you add a layer of abstraction on top of another layer of abstraction, but just to make your code shorter" True, you should only add layers of abstraction when there is a possibility of reuse.
–
Steven JeurisMay 15 '12 at 17:43

The problem with boilerplate is that it violates DRY. In essence, when you write boilerplate, you're repeating the same code (or very similar code) across a number of classes. When that code needs to get changed, it's not at all certain that the developer will remember all of the places that code was repeated. This leads to bugs where old APIs or old methods are used.

If you refactor out the boilerplate into a common library or parent class, then you only need to change code in one place when your API changes. More importantly, when unexpected changes happen, the code breaks in one place, and lets you know exactly what you have to fix in order to get everything working again. This is far preferable to a scenario where one change causes failures in dozens, or even hundreds of classes.

I'm going to take a different tact. Consistency in development is one of the most important features of software design, it's a critical tool in making applications extensible and maintainable but can be difficult to achieve when managing a team across multiple sites, languages and timezones.

If achieved, consistency makes code much more accessible "once you've seen one, you've seen them all", much cheaper to maintain and refactor, but above all, much easier to extend. When you write a library that does require some boilerplate, along with the power of your library you've also given the developer:

A starting point understand the preamble (boilerplate) into your functionality, most key classes and access points will usually feature as part of the boilerplate. This gives developers a starting point into the documentation

Expectations your placing on developers will become apparent, for example if you setup a tracing object as part of the preamble then developers will know where to log exceptions and information

Implicit understanding as you force the developer to go through your process of instantiating classes, they can infer the techniques they will need to access the rest of your library and have the opportunity to introduce them to any conventions you've used throughout your library

Easy validation when your boilerplate code is needed it can usually very easily validate itself with exceptions and guard clauses, preventing consumers from getting stuck much further down the line when you're already committed to a faulty process

Configuration of a library that requires boilerplate code is easy as there is already an obvious implementation point to customise the functionality for a single path of execution. This is particularly useful if your required boilerplate code is enhanced with the Factory or Command pattern

When the consumers of your library have a grip on the instantiation they can easily create private/extension methods, parent classes or even templates to implement the boilerplate code.