Earlier quoted context omitted.
Decades ago, when The Structure and Interpretation of Computer Programs taught us that programmers fundamentally do two things: abstraction and combination; and we are interested in programming languages insofar as they provide means to those two ends. The two classic "hard problems" of computer science - cache invalidation and naming things - are both aspects of abstraction. Cache invalidation is a special case of m…
I thought the two problems were cache invalidation, naming things, and off by one errors
That's not an abstraction, that's a layer of indirection
31–40 of 240 posts
Re: That's not an abstraction, that's a layer of indirection
#32But then you hear people describe abstraction ahem abstractly. "Abstraction lets you think at a higher level," "abstraction hides implementation detail," and it's clear that neither of those things are really abstractions.
As the OP mentions, we have a great term for those long chains of one-line functions: indirection. But what is TCP? TCP is a protocol. It is not just giving a higher-level way to think about the levels underneath it in the 7-layer networking model. It is not just something that hides the implementations of the IP or Ethernet protocols. It is its own implementation of a new thing. TCP has its own interface and its own promises made to consumers. It is implemented using lower-level protocols, yes, but it adds something that was fundamentally not there before.
I think things like TCP, the idea of a file, and the idea of a thread are best put into another category. They are not simply higher level lenses to the network, the hard drive, or the preemptive interrupt feature of a processor. They are concepts, as described in Daniel Jackson's book "The Essence of Software," by far the best software design book I've read.
There is something else that does match the way people talk about abstraction. When you say "This function changes this library from the uninitialized state to the initialized state," you have collapsed the exponentially-large number of settings of bits it could actually be in down to two abstract states, "uninitialized" and "initialized," while claiming that this simpler description provides a useful model for describing the behavior of that and other functions. That's the thing that fulfills Dijkstra's famous edict about abstraction, that it "create[s] a new semantic level in which one can be absolutely precise." And it's not part of the code itself, but rather a tool that can be used to describe code.
It takes a lot more to explain true abstraction, but I've already written this up (cf.: https://news.ycombinator.com/item?id=30840873 ). And I encourage anyone who still wants to understand abstraction more deeply to go to the primary sources and try to understand abstract interpretation in program analysis or abstraction refinement in formal verification and program derivation.
Re: That's not an abstraction, that's a layer of indirection
#33How did "abstraction" and "hiding complexity" become perceived as such fundamental virtues in software development? There are actual virtues in that ballpark - reusable, reliable, flexible - but creating abstractions and hiding complexity does not necessarily lead to these virtues. Abstraction sounds no more virtuous to me than indirection.
Re: That's not an abstraction, that's a layer of indirection
#34I find that I need to debug my abstractions frequently, while I’m first writing my code, then I never need to dig into them, ever again, or they do their job, and let me deal with adding/removing functionality, in the future, while not touching most of the code.
That’s why I use them. That’s what they are supposed to do.
Because they are abstractions, this initial debugging is often a lot harder than it might be for “straight-through” code, but is made easier, because the code architecture is still fresh in my mind; where it would be quite challenging, coming at it without that knowledge.
If I decide it’s a “bad abstraction,” because of that initial debugging, and destroy or perforate it, then what happens after, is my own fault.
I’ve been using layers, modules, and abstractions, for decades.
Just today, I released an update to a shipping app, that adds some huge changes, while barely affecting the user experience (except maybe, making it better).
I had to spend a great deal of time testing (and addressing small issues, far above the abstractions), but implementing the major changes was insanely easy. I swapped out an entire server SDK for the “killer feature” of the app.
Re: That's not an abstraction, that's a layer of indirection
#35How did "abstraction" and "hiding complexity" become perceived as such fundamental virtues in software development? There are actual virtues in that ballpark - reusable, reliable, flexible - but creating abstractions and hiding complexity does not necessarily lead to these virtues. Abstraction sounds no more virtuous to me than indirection.
Abstraction is good, in the way that leverage is good in the physical world: it is not always necessary, but people who are aware of the tool are vastly more capable than those who are not.
Re: That's not an abstraction, that's a layer of indirection
#36How did "abstraction" and "hiding complexity" become perceived as such fundamental virtues in software development? There are actual virtues in that ballpark - reusable, reliable, flexible - but creating abstractions and hiding complexity does not necessarily lead to these virtues. Abstraction sounds no more virtuous to me than indirection.
The only way we accomplish anything is abstraction. It's the basis of all computing.
Re: That's not an abstraction, that's a layer of indirection
#37Perhaps this is a minor nitpick, but > Abstractions are also the enemy of simplicity. Each new abstraction is supposed to make things simpler—that’s the promise, right? Not exactly, no. The purpose of abstraction is to hide implementation detail, and thereby insulate one part of the codebase/application/system from variations in another. Graphics APIs for example - yes your code may be simpler for not having to deal…
>> but the core benefit is that the same code should work on multiple different hardware devices. I came here to say this. Attractions act as a bridge between things which allow those things to change independently. Using an ORM allows my program to easily work against multiple sql databases. Using a compiler allows me to target different hardware. Using standard protocols allows me to communicate with different prog…
A curious example, since most developers who've worked on any project with significant amount of data in a database would likely disagree.
IMO, ORMs mostly allow using programming-language-of-choice as a syntax for relational queries instead of constructing it by hand on top of serialization and deserialization of objects into rows and vice versa.
Re: That's not an abstraction, that's a layer of indirection
#38Perhaps this is a minor nitpick, but > Abstractions are also the enemy of simplicity. Each new abstraction is supposed to make things simpler—that’s the promise, right? Not exactly, no. The purpose of abstraction is to hide implementation detail, and thereby insulate one part of the codebase/application/system from variations in another. Graphics APIs for example - yes your code may be simpler for not having to deal…
“The purpose of abstraction is not to be vague, but to create a new semantic level in which one can be absolutely precise.” — Edsger Dijkstra But sometimes a new semantic level isn’t needed. Abstraction gets so much press when you might just need some good ol’ fashioned information hiding and separation of concerns.
that's exactly what you do to implement an abstraction isnt it?
Re: That's not an abstraction, that's a layer of indirection
#39Perhaps this is a minor nitpick, but > Abstractions are also the enemy of simplicity. Each new abstraction is supposed to make things simpler—that’s the promise, right? Not exactly, no. The purpose of abstraction is to hide implementation detail, and thereby insulate one part of the codebase/application/system from variations in another. Graphics APIs for example - yes your code may be simpler for not having to deal…
In short: good abstractions simplify by centralizing operational logic. But it's not until a certain scale where that option is more efficient from bespoke implementations.
That is if you think you'll probably need multiple implications, delay introducing an abstraction until you actually do.
Also, there are different ways of providing abstraction.
Perhaps you don't need to abstract the entire implementation but, as an example, rather change one parameter from passing a value to passing a function returning a value.
Re: That's not an abstraction, that's a layer of indirection
#40Earlier quoted context omitted.
>> but the core benefit is that the same code should work on multiple different hardware devices. I came here to say this. Attractions act as a bridge between things which allow those things to change independently. Using an ORM allows my program to easily work against multiple sql databases. Using a compiler allows me to target different hardware. Using standard protocols allows me to communicate with different prog…
> Using an ORM allows my program to easily work against multiple sql databases. A curious example, since most developers who've worked on any project with significant amount of data in a database would likely disagree. IMO, ORMs mostly allow using programming-language-of-choice as a syntax for relational queries instead of constructing it by hand on top of serialization and deserialization of objects into rows and vi…