Headers, babies, and bathwater

I claim that by eliminating the C/C++-style dichotomy between headers and implementation, most modern programming languages have thrown out the baby with the bathwater.

Don't throw out the baby with the bathwater! Photo credit: StubbyFingers (Flickr)

Don’t throw out the baby with the bathwater! Photo credit: StubbyFingers (Flickr)

If that sounds crazy, just hang with me for a minute.

I know my claim runs counter to popular wisdom; have a look at this thread on stackoverflow.com. Designers of languages like python and go and D and ruby and java consider it a feature that developers don’t have two redundant pictures of the same functionality. This comment from the C# 5.0 specification is typical:

“Because an assembly is a self-describing unit of functionality containing both code and metadata, there is no need for #include directives and header files in C#. The public types and members contained in a particular assembly are made available in a C# program simply by referencing that assembly when compiling the program” (p 3).

I agree.

Sort of…

Bad headers are a royal pain

It can be onerous to maintain the parallelism between a .h and a .cpp. And most C/C++ headers are managed so poorly that the benefits you might claim for them are theoretical rather than real. Three common antipatterns that I particularly detest: Continue reading

Good fences make good neighbors

In Robert Frost’s poem, “Mending Wall”, two farmers meet each spring to rebuild the rock wall between their properties. One farmer is the narrator. He notes that the unseen forces of winter and weather always cause some decay (“something there is that doesn’t love a wall”), and he wonders why the wall is necessary. There’s apple orchard on one side, and pine forest on the other–it’s not as if something will be kept in or out. The other farmer answers with the repeated aphorism “good fences make good neighbors.”

photo credit: DragonWoman (Flickr)

This poem could be a treatise for the principle of encapsulation in software. In software as in life:

  • Something there is that doesn’t love a wall.
  • Good fences make good neighbors.

What doesn’t love a wall?

Subroutines, formal interfaces, data hiding, class hierarchies, the pimpl idiom, and similar mechanisms all create barriers in software between consumers and providers of functionality. These techniques are well known, but we still have codebases littered with protected data members, unnecessary class declarations in headers, goto, and other suboptimal choices.

Why? Continue reading