Lets Have Three Abstraction Layers
minimal.app
minimal.app
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.
Conway's Law is an observation that what you describe is what often happens anyways. Organizational structure influences system design and structure.
I.e. the interface isn’t an objective fact, it’s a normative way of framing a boundary.
Everybody can use those groups to arrange the universe, but there will be widespread disagreement over who belongs in what category. :P
- 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'll update the essay if I learn anything striking while applying the principle in my life and work.
> 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.
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
If so, how will you demonstrate it?
That's the important question for people interested.
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.
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.
* 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?
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 also tempting to make up arbitrary rules that make no sense and only work in one blogger's very specific thought bubble.
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).
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
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.
Avoid frameworks, use libraries, and use good abstractions that aren't going to "leak" - which usually means those grounded in mathematical laws.
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...
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.