You, a Driver, and a Taxi: Layers of Abstraction in Plain English

Máté Safranka
5 min readNov 12, 2018

--

A programmer’s job is, in essence, to create things that don’t really exist out of other things that don’t really exist. This abstract nature often makes it difficult to explain our work to laypersons, to the point where we ourselves might even wonder how we ever came to understand them. In what I’m hoping to grow into a series of articles, I will attempt to explain some fundamental programming concepts with simple, tangible metaphors.

The Basics

Imagine, if you will, that you want to get to a newly opened store. You call a taxi and get in, but when you give the address to your driver, they ruefully tell you that they’re not familiar in that part of town (and just to cover our bases, let’s also say their GPS is on the fritz). Luckily, you happen to know that neighborhood like the back of your hand, so you decide to guide the two of you there.

So, the driver starts the car, and waits for your instructions. Whenever you reach an intersection, you tell them to turn left, turn right, or proceed straight ahead. You continue to do so until eventually you reach your destination, at which point you tell them to stop.

Now, let’s consider this scenario and ask ourselves: Who’s driving the taxi?

“Do you feel in charge?” (Simone Acquaroli, Unsplash)

Technically, of course, it’s the driver. That’s kind of what the definition of a driver is. However, in a broader sense, it can be argued that it’s you. The driver isn’t really acting on their own; they are only there to translate your instructions (e.g. “turn left”) into a specific series of actions that can be applied to the car.

In programming terms, the driver creates a layer of abstraction between you and the car.

In general, a layer of abstraction is any piece of code whose purpose is to simplify the operation of something. In these scenarios, the thing that’s being abstracted (which can both be a piece of hardware, or another piece of code) usually has lots of small operations that don’t do much on their own. The abstraction layer takes these operations, groups them into predefined sequences, and publishes a much smaller, much simpler set of operations to the outside world. These sets of operations are also called interfaces.

In our example, the car has the following operations (among many others):

  • Apply/release the gas
  • Apply/release the brakes
  • Change gears
  • Turn left blinker on/off
  • Turn right blinker on/off
  • Turn steering wheel left
  • Turn steering wheel right
  • Reset steering wheel to center

These are what we call low-level instructions. When you tell the driver to “turn left”, you issue a high-level instruction, which they will translate into a sequence of low-level ones, such as:

  • Turn left blinker on
  • (Wait until oncoming traffic has passed)
  • Turn the steering wheel left
  • Apply the gas
  • (Wait until the car has turned by 90 degrees)
  • Reset the steering wheel to center
  • Turn left blinker off

You, as a passenger, do not have access to perform low-level operations directly on the car; either because you don’t know how, or because you lack the necessary privilege (e.g. do not have a driver’s license). Thus, you rely on a driver to act as your go-between, using a simplified interface.

Taking it Further

Abstraction layers make it much easier to control complicated systems, but their benefits go far beyond simple laziness. Consider this: in our scenario, how much does it matter to you what make and model the taxi is? Or, in fact, if it’s even a car? The answer is precisely zero (from a technical point, at least). As a backseat driver, your only concern is to have a driver whom you can tell to turn left, turn right, or go straight. The actual vehicle might as well be a minivan, a motorbike, a rickshaw, or a one horse open sleigh.

In programming terms, abstraction layers allow higher level code to be implementation-agnostic. In plain terms, abstraction layers give you the luxury of not caring.

Another important aspect is security. As I mentioned in passing a few paragraphs above, one of the reasons you may require a driver is because you yourself don’t have a license. If you were to sit behind the wheel, you might not know when or how to use the blinkers, the clutch or the gearbox; you could easily perform an invalid sequence of operations and stall the car at best, or cause an accident at worst. Abstraction layers can make sure you don’t do anything that would create an invalid output, or access data you’re not supposed to (whether by accident or on purpose).

This article is brought to you by the assumption that all licensed drivers know how to use their blinkers. Riiight? (Wikimedia Commons)

If you ponder our scenario a little further, you may also realize that there’s one more layer of abstraction at play. For example, what exactly needs to be done to make the car go faster? Obviously, the driver needs to step on the gas, but that action in and of itself does not cause acceleration. Valves need to be opened, fuel injection needs to be readjusted, to say nothing of transmission. In short, the assortment of pedals, levers and switches you control the car with are there to abstract the myriad of mechanisms working under the hood.

Any piece of software can have any number of abstraction layers stacked on top of one another. The browser you’re using to view this article isn’t drawing the pixels of text directly on the screen; it’s communicating with the presentation layer of your device’s operating system, which in turn communicates with the hardware layer, which communicates with the kernel layer, which then sends byte data to the screen’s hardware port, which is finally transformed into the electronic impulses necessary to make each pixel light up in the right color.

As a frontend developer (the definition of which will probably be a whole other article), I have zero idea how any of the layers I just listed actually work. In fact, I’m pretty convinced I got most of that wrong. There is no human alive today who can tell you exactly how all the parts of any device work. But, as we stated above, that’s the beauty of abstraction layers: they don’t need to know.

10 out of 10 developers are basically Charlie Brown. (Tom Simpson, Flickr)

Mate Safranka may not care what’s below the layers of abstraction, but he does care about creating high-quality digital products. That’s why he works at Supercharge (clearly not in marketing).

--

--

Máté Safranka

Frontend developer, learning confectioner, hobbyist game maker, amateur writer.