37 comments

[ 3.0 ms ] story [ 197 ms ] thread
Author here. I know it's a bit idealized (just three!), but that's the purpose, to provide a simple sense of direction as we try to create better abstractions or better exist with existing abstractions.

I'll update the essay if I learn anything striking while applying the principle in my life and work.

I didn't like the dishwasher example:

> For example, knowing that loading the dishwasher takes place on the Human abstraction layer will encourage us to not over optimize the position of dishes, to not over-clean the dishes before they go into the dishwasher.

The position of dishes also has a great bearing on the Nature/physics layer. Also, what's the actual abstraction in this example? A programming example since the area is mentioned would be more compelling.

I also don't believe in choosing/standardizing abstractions before looking at each case. Maybe it would better to frame abstractions as possibly/mostly addressing one of these broad concerns.

(comment deleted)
The dishwasher example is a leaky abstraction (like all abstractions)

Cleaning the dishes before putting them in the dishwasher is done purely because of physics reasons, but it surfaces into the human layer. Likewise the position of the dishes etc

You could try to design a dishwasher that minimizes this "leakage", for example, by providing a robotic arm to remove the bulk of food, but not surfacing lower level details into the higher level layers is fundamentally impossible

But that surfaces to the human layer as a precondition, just because the reason for the precondition is based on the physical layer doesn't necessarily mean it breaks the abstraction. I still need no knowledge of the how the dishes actually get cleaned.
You need knowledge or you will put a closed jar in and discover it doesn't clean inside.
Please do! I like the idea a lot, and I'm really interested to hear about a real-life engineering decision you apply it to.
Is it less leaky than all the pre-existing systems of abstractions available?

If so, how will you demonstrate it?

That's the important question for people interested.

Hey! interesting article.

I noticed that you published it using Minimal app.

I was curios how I could see other blogs published by you? There didn't seem to be a link pointing to your collection of blogs.

I like this approach to thinking about abstractions. It's easy to forget /why/ you are abstracting something, and this gives some perspective and structure to it.
I think I like the idea. This is easily stated as having different framings, though? Similarly, I could ask what makes this different from "affordances, features, and constraints?"
This is interesting! I would love to see more concrete examples, though.
Yes, would be much more effective with examples demonstrating the issue in that 3rd to last paragraph.
I think all programmers should try to be a bit like business analysts where they can. Often the organization will prevent you having the require information to do this. They have already decided what you are going to build. But if you get a chance to talk to end users it can make you more empathetic.

I think this was a tenet of "agile" that the suits haven't really pushed hard on (they like the sprints and pseudo-work-tracking aspects, such as how many points did we crush this err.... quarter).

I think what we desparately need is a way to move between abstraction layers easily.

For example, right now, when you pick a framework, you're kinda stuck with it. Even if you could in theory move to a lower abstraction layer (by modifying the framework's source code itself), nobody does this in practice. So you're kinda locked into that layer of abstraction.

Imagine how amazing it would be if it didn't matter what level of abstraction you start on. You could seamlessly move between layers and modify wherever seems reasonable.

I don't yet see how we could achieve this. But I think this would require abandoning our current notion of abstraction entirely, or at least introducing some major constraints on it.

If anyone has any thoughts on this at all, I'd love to hear them.

Proper abstractions work. Look at what happens in the functional-programming world; if you provide an instance of monoid (say) for your datatype, you can use all the functions that work on monoids, but your datatype still retains its full detail and you can use your original datatype wherever you like.

Avoid frameworks, use libraries, and use good abstractions that aren't going to "leak" - which usually means those grounded in mathematical laws.

I disagree. All abstractions are leaky, to a certain extent.

The abstractions in FP circles are only not considered leaky because performance concerns are often secondary, and only correctness is considered.

https://www.joelonsoftware.com/2002/11/11/the-law-of-leaky-a...

I'm aware of that post and it's bollocks. None of its examples actually work, and even if they did they wouldn't be enough to prove a general law.
I think they make a lot of sense - genuinely curious what you mean. Could you explain in more detail?
Writing your application using UDP rather than TCP doesn't mean it will continue to work when you unplug the network cable. That's not the abstraction leaking, that's the premises being violated. TCP is actually very specific about what it does and doesn't guarantee.

That SQL example may have been a real bug in one database 20 years ago, but it's not something that happens in reality. Query planners work well enough that you can't generally beat the query planner - PostgreSQL won't even let you try, quite deliberately.

And if you look at even one of the classic FP examples like monoid, not only do they not leak, but you can literally mathematically prove that they don't. If you have two lists of a monoid, sum(a) + sum(b) will always equal sum(a + b). The whole post is just a failure of imagination; rather than proposing that all abstractions are leaky because you can't think of any good ones, a better post would ask what it would take to constitute a valid abstraction and then try to figure out whether that's possible or not.

I know of something in this area, but I was involved in it and prefer to maintain my pseudo anonymity. If you care to and email me at my username @ gmail I'll share over that channel.
The author admits this is an ideal - to be a bit more pragmatic - I would argue we can reduce problems to one of three failure categories and thus have a solution based upon one of those three.

Failures are either expected, unexpected, or unknown. Wear and Tear is expected. Unexpected failures are physical damage or misuse. The unknown failure won't report a failure nor be predictable.

Code readability does not apply to user level. The user is concerned about error messages - these should be written in a way that is understandable to the human.

http for example has 3 digits - easy enough as learning 404 is easy. Microsoft and the 0x000..... is nonsense and useless.

Generally problems exist in three possible realms.

Let's use a human infant as an example - one of life's most wonderful creations yet lacks a manual, proper logging, and useful errors yet require a Severity 1 response time.

The infant is crying because of one of the three: need, want, unknown. If the kid is clean, fed, rested - move onto want. If the child isn't bored or able to be satisfied, move onto addressing the unknown. This of course takes more effort, inspection, etc. That can be split into wait, advice, and emergency response.

With this level of abstraction I have helped new parents with addressing their child's needs. The details are not as important.

You do a bit of implicit mapping between terms in your description. Is this correct?

* expected => need

* unexpected => want

* unknown => unknown

I think you're onto something with the focus on failure modes.

It's interesting that your model and the author's model each have 3 layers. A few of the other proposed models in these comments also have 3 layers.

It's quite jarring to try to map your model to the author's model: I guess they are just fundamentally different ways of looking at abstraction?

I often wonder if I should be more explicit. Maybe you can help me.

There is a path, we are all on a path, linear in the sense that time moves in the same direction, without a pause or ability to stop, and on this path is a fork. We say a fork because it could be an intersection with near infinite courses but in reality we often limit the choice to ultimately two choices and while intentionally ignoring the third.

At the fork there is either a Left or a Right. The third choice, intentional or unintentional indecision leaves us still to react to either making a panic choice or hitting the wall.

The three layers or levels of abstraction allow for the This, That, and the Unknown.

Back to the failure modes. In troubleshooting there are finite paths one can take to determine the problem and also finite problems that cause the situation.

> It is tempting to solve every problem we encounter with an abstraction of the layer

It is also tempting to make up arbitrary rules that make no sense and only work in one blogger's very specific thought bubble.

I have been thinking along those lines for a while. I didn't take it quite from the same angle but it boils down to the same idea.

For me, each layer of abstraction should roughly correspond to people's roles.

In my line of work (finance) it's a little more complicated than what the article states.

There are people who specialize in deep computational optimization.

There are people who do micro financial models

There are people who do macro financial models

There are people who do user interfaces

There are people who do the piping between all these

The ideal to aim for is that each layer of abstraction is cut around those fairly well defined roles. Each person should be able to own their piece of the codebase and hopefully manipulate objects/languages of the right level for them.

In the dishwasher example, the middle layer should be cut in the "electronics layer" and the "hydrolics layer", the electronics layer interfaces with both the user and the hydrolics layer, but the hydrolics layer never interfaces with the user. And it's easy to see that the electronics and the hydrolics are not designed by the same person.

It's a way of framing things that makes sense for me.

https://en.wikipedia.org/wiki/Conway%27s_law

Conway's Law is an observation that what you describe is what often happens anyways. Organizational structure influences system design and structure.

I find it interesting that as our societies have become increasingly complex and we have organically implemented what we think is an efficient division of labor, we have ended up with people not only specializing across multiple sectors, but also in different layers of abstraction within the same sector. We have done all of this without even realizing that we were pushing people towards a different interface of the problem, but the same problem nonetheless.
Not sure I can prove it, but my intuition is that this actually flows in the opposite direction, i.e. we organically discover efficient organizational buckets and then ascribe boundaries and labels to those clusterings.

I.e. the interface isn’t an objective fact, it’s a normative way of framing a boundary.

Thanks I didn't know that one!
The three in this case to me is information architecture, user experience, and user interface. There are many sets of three. Each observer jockey's their own perspective.
"Upstream, Me, and Downstream."

Everybody can use those groups to arrange the universe, but there will be widespread disagreement over who belongs in what category. :P

I think you can reduce (abstract?) the number of role further:

- Builders. This would be software developers in the I.T. world.

- Users. Regardless of what their specific domain expertise (or lack) is in, those who utilise the system.

- Maintainers. Those who fix what's broken. "Repair techs" from the world of complex machinery, "software maintenance" in I.T.

Possibly also: sales & marketing, who describe and position the products, management, who oversee general operations, and logistics and/or operations, who fit the pieces together and support them outside general maintenance (an I.T. analogue might be DevOps or systems admins roles).

Each of these has their own perspective, goals, relationship, and set of concerns with the system. And whilst there may well be levels of expertise within each role, there's a larger set of uniform and consistent concerns and relationships each addresses as well.

In complex physical kit, you'll generally see such roles expressed as engineering, manufacturing, marketing, (customer) operators, logistics, maintenance (on-site repair and adjustments), and sales & marketing, or terms to that effect. The roles typically exist within software and information products as well, though of course not all physical analogues map directly. Within a complex product, you'll have the user interface, a maintenance or technician's interface, component-level design (which may or may not be designed for field maintenance), demo modes and marketing collateral (for sales/marketing), and considerations for the actual construction, packaging, and logistics supply- and delivery-chain support for the devices, etc.

Each of these is effectively a level of abstraction onto the end product.

I figure we want a kind of split-level economy:

The primary layer would be basically what this article calls the "Nature layer" and it involves using our science and technology to meet a minimum Standard of Living for everybody in an ecologically harmonious way.

Then on top of that I imagine we would have a kaleidoscope of creativity and production, a cornucopia of art and fashion and food and all the things that make it so epic and wonderful to be a human being.

I think the "Middle layer" will be largely subsumed under automation, to the extent that it's not an art or craft.

What we are seeing with the advent of AI etc. is that the ultimate question is "What is good?" or in other words, "What are People For?"

(Cf. Wendell Berry: "What are People For?" https://openlibrary.org/books )/OL27154477M/What_are_people_for

I try to consider "general concerns" rather than "layers of abstraction" when designing and implementing systems, especially in teams. These concerns vary by project but always include the constraints of physics and humans. All other concerns emerge.