Abstraction: More than a process, the idea of Software

What abstraction is and what role it has in software.

What is it

One of the human traits that enables today’s modern society is the ability to abstract. It complements our tendency to document our discoveries and allows us to stand on the shoulders of giants to keep going further.

Philosophically speaking, as part of epistemology [1] (the branch of Philosophy that handles the Theory of Knowledge) abstraction is a type of comparison [2] (similar to metaphors, analogies and generalizations), a technique to acquire knowledge.

Abstraction allows us to use systems and reason about ideas that otherwise would be too complex to fully understand. An intellectual divide to conquer skill with which we can accomplish a goal without getting bogged down in the details. It allows us to see patterns in different systems and generalize them into models, therefore making the world easier to reason about (think biology taxonomy, weather models, etc).

Abstraction in software

Every time we import a library into a software project we are abstracting something. Most of the time we do not care how the library does it (barring for security or performance concerns), as long as it does. We stand on the shoulders of giants by being able to use it. We move faster because we do not need to waste time reinventing the wheel.

We can tackle increasingly complex systems because for each new system we only need to actually develop a couple of “groundbreaking” features (or more commonly: we just need to integrate several already existing modules and ideas to solve our specific instance of a common problem).

We detect patterns in the code we are writing and generalize them into functions, into classes, into packages.

Abstracting something is to focus in the end goal and forgetting (at varying degrees) the details. It also involves trust.


Consider a language translation library. Users of the library do not care how the library translates the input, they only care that it outputs a seemingly correctly translated version in the end. Most users of a library like this will not be able to know how good the translation provided by the library is, since they don’t speak one of the languages. Users of this library are expected (from the library developer POV) to trust the output to be correct.

Despite being software, the translator library expertise core ain’t really software. A computer doesn’t speak neither understands what a human may say: it “simply” receives instructions about how to do it (the programming step). To develop and implement effective translation algorithms it’s necessary linguistics expertise.

The need to specialize (becoming an expert/specialist) is increasingly connected with the cognitive complexity of a society, not only by technical reasons (more complex systems) but also social (differentiation factor).

If the ancient geniuses, like Aristotle, were at the time specialists in physics, philosophy, biology, literature among other fields, it’s currently unthinkable for someone to be an expert even in their whole field of action, and within a field of knowledge that expertise is getting increasingly narrower.

From an abstraction point of view, the notion of a specialist is relevant if we consider that the higher abstraction a system has the more trust it needs around it.

Consider a compiler for some programming language. Programmers need to use some sort of compiler, however, even though it being the most important tool for a programmer, nobody constantly asks himself if the binary code generated by the compiler is an exact equivalent of the written source code.

This level of trust is due to the fact that compilers were developed by compiler experts who historically have always produced good compilers that generate binaries that do what was intended, and when they don’t, 99% of the time during the debugging process faults are found at the user source code level.

Whoever uses a compiler may (and should) know how it works in abstract or basic terms. Nevertheless, the vast majority of compiler users certainly won’t be experts in compiler techniques, thus they can’t just open the compiler to check if the generated code will always be correct. A compiler user, above all else, trusts that the generated code is always correct (and hopefully efficient).

Trust plays an important role in complex systems (the user doesn’t know how it works, so he can’t check its quality by himself). It also plays a role in proprietary systems.

In proprietary systems it’s not given to the user, being him more or less literate in the matter, the chance of reading the system’s source code, and for this reason the users of the software use it trusting that it isn’t betraying them, being it in technical, moral or privacy terms. This is a more forced type of abstraction intended to protect the intellectual property of the software designers, which although comprehensible for economic reasons, it is a completely man-made type of abstraction made possible by the technical nature of software (traditionally this would be enforced by obscurity - like the coca-cola recipe).

References

This post is inspired in a another blog post I wrote more than 10 years ago at https://asuol.wordpress.com/2013/08/21/abstraction/#more-109

[1] https://en.wikipedia.org/wiki/Epistemology
[2] https://philosophy.stackexchange.com/questions/101927/conceptualizing-metaphor-and-analogy-with-abstraction