Live data from Hacker News

That's not an abstraction, that's a layer of indirection

fhur.me

71–80 of 240 posts

Re: That's not an abstraction, that's a layer of indirection

#71

Pretty easy to give generic advice without examples. “Write more tests, but not too many” “Use good abstractions where appropriate?” “The next time you reach for an abstraction, ask yourself: Is this truly simplifying the system? Or is it just another layer of indirection?” It’s easy to create a strawman here (the FactoryAdaptorMapper or whatever) but in reality this kind of generic advice doesn’t help anyone. Of cou…

I can see the value of examples, but in this case I appreciate the post largely for its universality and lack of examples. On reading it, examples from past and present experience spring immediately to mind, and I'm tucking this away as a succinct description of the problem. Maybe I can share it with others when more concrete examples come up in future code review. A principle takes skill the apply, but it's still wo…

> examples from past and present experience spring immediately to mind

Examples of what?

Picking the wrong abstraction? Regretting your mistakes?

I can certainly think of many examples of that.

How you unwrapped an abstraction and made things better by removing it?

I have dozens of battle stories.

Choosing not to use an abstraction because it was indirection?

Which is what the article says to do?

I’m skeptical.

I suspect you’ll find most examples of that are extremely open to debate.

After all, you didn't use the abstraction so you don’t know if it was good or not, and you can only speculate that the decision you made was actually a good one.

So, sharing that experience with others would be armchair architecture wouldn't it?

That’s why this article is arrogant; because it says to make decisions based on gut feel without actually justifying it.

“Is this truly simplifying the system?”

Well, is it?

It’s an enormously difficult question to answer.

Did it simplify the system after doing it is a much easier one, and again that should be the advice to people;

Not: magically do the right thing somehow.

Rather: here is how to undo a mistake.

…because fixing things is a more important skill and (always) magically doing the right thing from the start is impossible; so it’s meaningless advice.

That’s the problem with universal advice; it’s impossible to apply.

Re: That's not an abstraction, that's a layer of indirection

#72
post #37

Earlier 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…

Yes, ORMs came to mind for me as an example of indirection without abstraction. If you accept OP’s litmus test of “how often do I have to peek under the hood” I think ORMs generally don’t score particularly well.

Re: That's not an abstraction, that's a layer of indirection

#75

Perhaps 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…

That would be encapsulation, not abstraction.

Re: That's not an abstraction, that's a layer of indirection

#76

Perhaps 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…

> allows my program to easily work against multiple sql databases

How many times have you required that your program runs against different sql databases without modification?

I mean, how many times have you required your plane to be able to fly in the different atmospheres of different planets of the Solar System?

Unless you are NASA, I suggest you cut the complexity and just make a plane that can fly well on Earth's atmosphere.

Re: That's not an abstraction, that's a layer of indirection

#77
> Think of a thin wrapper over a function, one that adds no behavior but adds an extra layer to navigate. You've surely encountered these—classes, methods, or interfaces that merely pass data around, making the system more difficult to trace, debug, and understand. These aren't abstractions; they're just layers of indirection.

“No added behaviour” wrapper functions add a lot of value, when done right.

First off, they’re a good name away from separating what you’re doing from how you’re doing it.

Second, they’re often part of a set. E.g. using a vector for a stack, push(x) can be just a call to append(x), but pop() needs to both read and delete the end of the vector. Push in isolation looks like useless indirection, but push/pop as a pair are a useful abstraction.

A consequence of adding these two points together is that, if you have a good abstraction, and you have a good implementation that maps well to the abstraction, it looks like useless indirection.

Another consequence is that those pass-through wrapper functions tell you how I think the implementation maps to the domain logic. In the presence of a bug, it helps you determine whether I got the sequence of steps wrong, or got the implementation wrong for one of the steps.

Ultimately, the two aren’t completely independent —indirection is one of the tools we have available to us to build abstractions with. Yes, people misuse it, and abuse it, and we should be more careful with it in general. But it’s still a damned useful tool.

Re: That's not an abstraction, that's a layer of indirection

#78

Perhaps 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…

While this is how the term is often used, I think it's cavalier use of language and confuses abstraction for modularity , and this linguistic confusion is one of the reasons a lot of programmers write bad "abstractions". Organizing your code into components that are as independent as possible is a good practice and is the pursuit of modularity. A proper abstraction on the other hand, is a generalization that simplifi…

Yes, abstraction and modularity are coincident but distinct topics, and my last paragraph implies that I am equating those two things. Good point.

I disagree that considering a text file as a set of lines really qualifies as an abstraction; it's just a different representation of the data - you could instead choose to use a list of words or a tree or whatever. An abstraction is a general interface to a concrete thing that allows you to substitute different but similar concrete things without changing the consumer of those things. The Linux filesystem is a great example - I can 'cat' basically anything that has a path, and some driver will pull data from the associated endpoint and display the data on screen. "File" is the abstraction, and consumers of files need not care about the specifics of communicating with the underlying devices. Such a system is also modular, but it's hard not to be when your abstraction is well conceived.

Perhaps we're saying the same thing with different words?

Re: That's not an abstraction, that's a layer of indirection

#79

The best way to achieve a good abstraction is to recall what the word meant before computer science: namely, something closer to generalization . In computing, we emphasize the communicational (i.e. interface) aspects of our code, and, in this respect, tend to focus on an "abstraction"'s role in hiding information. But a good abstraction does more than simply hide detail, it generalizes particulars into a new kind of…

Yes, abstraction and generalization are properties you'd rather look for the second time around. Someone was already warning about this 25 years ago [1]:

You have a boring problem and hiding behind it is a much more interesting problem. So you code the more interesting problem and the one you've got is a subset of it and it falls out trivial. But of course you wrote ten times as much code as you needed to solve the problem that you actually had.

Ten times code means ten times cost; the cost of writing it, the cost of documenting it, it the cost of storing it in memory, the cost of storing it on disk, the cost of compiling it, the cost of loading it, everything you do will be ten times as expensive as it needed to be. Actually worse than that because complexity increases exponentially.

This person did his own CAD software from scratch in order to make custom chips [2].

[1] https://www.ultratechnology.com/1xforth.htm

[2] https://en.wikipedia.org/wiki/Charles_H._Moore

Re: That's not an abstraction, that's a layer of indirection

#80

Perhaps 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 to hide implementation detail Technically, that's encapsulation, though the sentiment is close, I think. I rather view it as a matter of semantics. At one low level, you have operations that deal with some concrete interface or API, etc. You bundle those operations up behind an abstraction, providing methods whose names involve your application domain. Perhaps they are still at a techn…

Hmmm I prefer Wikipedia's definition:

> In object-oriented programming languages, and other related fields, encapsulation refers to one of two related but distinct notions, and sometimes to the combination thereof:[5][6]

> - A language mechanism for restricting direct access to some of the object's components.[7][8]

> - A language construct that facilitates the bundling of data with the methods (or other functions) operating on those data

The hiding is absolutely the point of abstraction, in the sense that caller can manipulate the subsystem without knowing about (important) inner details of it. As I said, graphics drivers are a great example - I just want to put a triangle on the screen, I don't want to care about the registers I have to set on an NVidia card vs those on an AMD card, or what their memory maps look like, and I don't want to have to rewrite my code when they release a new generation of hardware. Drawing a triangle is an abstraction, hiding away the details of how a specific graphics card achieves that.

Think about what the word 'abstract' means - the idea of a 'human' is an abstraction for bundles of molecules conforming to a general pattern with broadly similar qualities but almost infinite variability. The word conveniently hides a wealth of detail that we usually don't need to think about; if I tell you there are three humans in a room, you can make use of that information without knowing anything about their exact physical attributes or who they are.

I would refer to what you're describing as 'modelling' - these are related topics but I don't see them as the same thing.

Post reply on HN