Saturday, October 14, 2006

 

The Law of Leaky Abstractions

The Law of Leaky Abstractions - Joel on Software

Ok, my first real post and I'm leaching off of Joel.

This is one of the most insightful articles I've read on software development. Leaky abstractions occur everywhere while developing software. Every software developer has run into these leaky abstractions and most of them don't even know it.

Probably the most common form of abstraction that leaks is integer arithmetic. Sure, everyone one knows that 1 + 2 = 3. This is true for any language, on any platform. What about 100 + 101? Is that equal to 201? Of course.. unless you are using a signed byte as your data type, in which case it happens to equal -55.

Even something as simple as integer math breaks down eventually. Fortunately the vast majority of developers are aware of integer wrap around, but few of them think of it in a more formalized way. By formalizing this concept, it allows us to look for other abstractions that may be leaking without our explicit knowledge.

There is an import point implied by the article. In order to identify the leak, you need to understand exactly how the abstraction works. This can be problematic. Sure most developers understand the basics behind integer math, but what about much more complex abstractions, like compilers?

This is why a good software engineer understands not just how to use his tools, but how those tools work. Too often I've interviewed potential developers who seemed to think that it didn't matter if they knew what was happening when they hit "build".

That's why I ask the question "how are virtual functions implemented in C++" during an interview. This is such an important concept, because those that don't know (or worse, don't care) must be regarding the very language that they work with as a magic box. When that magic box fails, as it so often does, if you don't know what is happening, or what should be happening, you are stuck.

If you understand the abstractions in use, you not only know how to fix them when they go wrong (or at least can come up with a workaround), but you gain insight into how to use the abstraction more efficiently. I don't need to memorize a rule about whether or not my class's destructor needs to be virtual. I can deduce the correct answer because I have the knowledge about the implementation. This applies to any abstraction. The more we know about the implementation of the abstraction, the less rote memorization is require to use the abstraction correctly.

This of course brings up the question of how much of the implementation should we know. It is a law of diminishing returns here. Do we need to know about pointer arithmetic, or call stacks, or calling conventions? They are certainly useful for other abstractions, but in terms of virtual functions, they don't add a whole lot of useful information. The real trick is knowing how far down you need to drill before you are just learning for the sake of learning.

Not that there is anything wrong with that...

 

Is this thing on?

Welcome to my first blog post. I've started this blog with the intent to discuss software engineering. I hope to put up some articles that I have been thinking about writing.

But don't hold your breath. It could be a while before I have a chance to write more than a very brief intro.

This page is powered by Blogger. Isn't yours?