Jesús Burgos Maciá

Leaky abstractions


It’s said that an abstraction is leaking when part of the complexity it’s supposed to hide sneaks into the surface, exposing it in some way.

Rational numbers as an example

Setun Computer

Even though all computer hardware works with a binary numeric system (with some rare exceptions) we’re able to use arithmetic with decimal numbers very easily with any programming language. Aren’t abstractions awesome?

However, you may find surprises like the following, in Ruby:

0.1 + 0.3
# => 0.30000000000000004

But let’s not blame Ruby just yet, let’s try with Python:

0.1 + 0.3
# => 0.30000000000000004

Javascript (Node.js):

0.1 + 0.3
// => 0.30000000000000004

Etc.

This is a problem related to the way we store floating point numbers, using the IEEE-754 double precision format. This is very well explained in Python’s documentation, and it’s a good example of how an abstraction can leak.

The computer creates the illusion that we can use rational numbers, but there’re cases where it shows an unexpected behavior that is only understood when you know the underlying details.

How bad is this?

It’s bad because it means we still need to understand what’s beneath the abstraction in order to use it. But still the abstraction may be useful.

All non-trivial abstractions, to some degree, are leaky.

Joel Spolsky

In a wonderful world abstractions wouldn’t leak at all. But we live in the world were Internet Explorer exists, not wonderland.

They always exist because in some cases we can’t avoid the leak, but then we have to make an extra effort to communicate the leaking detail to whoever may be surprised by it, which could be another programmer or maybe the end-user. This idea is well explained in this article by Fragner Brack.

For example, imagine a user of a banking system making a money transfer. The UI to make the transfer doesn’t specify the time it takes for the receiver to see the incoming amount in their account. However the user made this operation several times in the past so we’ve set his expectations to have this completed in 1 hour.

One day, the user makes a transfer but this time the servers are really busy because the operation was requested while the daily batch processing was being carried out, so it doesn’t get fully processed until 3 hours later.

By explicitly showing something like “Most transactions take about 1 hour but it may take up to 24 hours” in the UI we’re probably saving a few calls to the support center. And more importantly, we’re preserving the trust of the user.

A glimpse of hope

So all abstractions are leaking, but I think just the fact of being conscious of this concept is going help in the future when we create or use an API, web application, the file system in your OS, the networking protocols, etc.

Also it’s going to lead us to think about how leaky our abstractions are, which is a good exercise. For example, if you find yourself explaining too many details of your internals, the universe may be telling you that your abstraction doesn’t fit there.

I think the most valuable contribution you can do to your software project as a programmer is create good abstractions, at every level of the application – internally and at the front-end. Interestingly, this may end up changing the way other people on the company perceives the business logic.

So, creating the right abstractions is definitely super important.