When I was watching the nice Channel 9 interview series on the Windows kernel, my brain associated wildly, and I got a new perspective on Joel Spolsky‘s "The Law of Leaky Abstractions". There are in fact two (at least) interesting kinds of abstraction leaks. And it might be that we can get rid of one of them. Or I’m just too optimistic, we’ll see!
By Joel’s law on leaky abstractions, there should be some "leaks" between the Windows kernel and the level of managed code. And surely there are, for example "iterating over a large two-dimensional array" listed in Joel’s article on "The Law". And I’m pretty sure we can construct some example where code won’t be portable between Linux and Windows because of the thread scheduler working differently on the two platforms. These are "leaks" that appear because there isn’t a specification of what should happen in these cases. And since we’re working on a higher abstraction level, we don’t want to specify that for every possible case, because then we wouldn’t have a useful abstraction. This part of the Law seems to be the unavoidable one.
Certainly we could improve our specifications (abstraction levels), in particular, I would suggest that people started adding performance stuff to their language specifications. "Sandboxing", for example, should include not only restrictions on what files an application can open and the like, but also restrictions on how much CPU may be used, how much network traffic is allowed, and so on. But nevertheless, we probably need to know everything down to the transistors (hm, perhaps not?) in order to be good software developers.
Now for the second kind of "leak", the one I’m more optimistic about. It’s represented by Joel’s examples on COM, ASP (but not in the sense Joel describes), C++ and code generation tools. These in fact represent bad abstractions, because these technologies aren’t really abstractions! When you’re working with those, you’re allowed to do stuff on the previous level of abstraction; that level simply isn’t hidden.
The reason that managed code (and other virtual machines, of course) is good at removing "leakages of the second kind", is that the previous level of abstraction is really hidden. Yes, I know there’s always a native API, right. But when you’re using it you should first sign the statement "I hereby accept the risk of getting abstraction leaks"!
That is, with managed code, you have a well-defined entry point to exposing yourself to such abstraction leaks. If you don’t use it, you shouldn’t need to suffer from those abstraction leaks. Makes sense?
[Update: I’ve added final section as a clarification.]