Live data from Hacker News

The Cost of Abstraction (2016)

250bpm.com

21–30 of 65 posts

Re: The Cost of Abstraction (2016)

#21
post #9

I find that there's two core points that help me figure out where I'm missing some form of abstraction: the body of a function should only operate on a single level of abstraction, and it should only know technical details about one thing. If you're writing some database code, having high-level fetchMyEntity() calls mixed with connection/resultset/cursor logic is bad news. If you're writing something that reads from…

The "Simple Made Easy" talk describes this as the root of complexity in an application. Mixing and tying various subcomponents that shouldn't have to know each other exist.

Re: The Cost of Abstraction (2016)

#22
post #6

Earlier quoted context omitted.

It's almost like he's making a small non-real-life example to illustrate his general point, which is not confined to the particular example.

Your comment reads just as well without the condescending "It's almost like" at the beginning

Yeah, but the condescension was put in to counter-balance the parent's facile dismissal of the author/TFA.

In other words, to add a cost (the possibility of being dismissed/sneered back) to such dismissals.

Re: The Cost of Abstraction (2016)

#23
post #17

Earlier quoted context omitted.

Which is not to say that we shouldn't wrap dependencies. We absolutely should. But by default, the wrapper should not offer an abstraction that is so flexible that the dependency can be exchanged. Instead, it should start with the actual problem, by offering only abstractions that (a) make sense in the context of the program and (b) translate well to concepts of the dependency/library. For example, hiding POSIX-style…

Dependencies should be treated like if it was your own code. After you have replaced some API for the third time you can start thinking about wrapping it.

Or if you start with multiple wrapped dependencies from the start, the library is frequently updated and/or you touch the library in many places in your code across multiple projects especially, those are good places for wrappers/facades/adapters.

An example would be in games when you submit an achievement or leaderboard score to a third party such as Apple GameCenter, Google Play Game Services, or other systems like Amazon Game Circle, web or custom. These libraries are frequently updated, they change per platform and you will touch them many places in the codebase, so wrapping them in a progression/statistics/achievements wrapper/facade/adapter is smart from the start.

Re: The Cost of Abstraction (2016)

#24
post #22

Earlier quoted context omitted.

Your comment reads just as well without the condescending "It's almost like" at the beginning

Yeah, but the condescension was put in to counter-balance the parent's facile dismissal of the author/TFA. In other words, to add a cost (the possibility of being dismissed/sneered back) to such dismissals.

And yet the author is still making a dumb point with an even dumber example "polymorphism so hard me brain hurt aBstRaCtIoN bad"

Re: The Cost of Abstraction (2016)

#25
post #21
post #9

I find that there's two core points that help me figure out where I'm missing some form of abstraction: the body of a function should only operate on a single level of abstraction, and it should only know technical details about one thing. If you're writing some database code, having high-level fetchMyEntity() calls mixed with connection/resultset/cursor logic is bad news. If you're writing something that reads from…

The "Simple Made Easy" talk describes this as the root of complexity in an application. Mixing and tying various subcomponents that shouldn't have to know each other exist.

> Mixing and tying various subcomponents that shouldn't have to know each other exist.

And this is the real trap when dealing with abstractions - maybe the implementations of two different operations are the same, but if the semantics are different then de-duplicating them creates an unnecessary dependency between the two. The more cross-links in your application structure, the harder it is to do anything without breaking everything.

Re: The Cost of Abstraction (2016)

#26
post #5

I've seen excessive abstraction kill projects time and time again. The crime scene is similar in every case: - What if we ever need to change database server or driver? Proceeds to write a layer to abstract data access - We might have different login forms one day? LoginFormFactory it is - This code hits our KV Redis/memcache/NoSQL by calling the driver lib directly? Can't have that, I'll write a CacheStorage or Docu…

Abstraction isn’t always applied for rewrite flexibility reasons, in fact I claim it rarely is. Often it is used primarily as a way to decompose complexity: I want to write this component without deeplh considering specific interdependencies so I’ll just abstract those away and get on with it. The code will only be composed with specific things, but considering all those interactions up front is a PITA.

Overly abstract code could just be a sign of a programmer working through a problem that was not well understood (either by everyone or just themselves). The second or third time they do the same task, the code is bound to be less abstract because they are more comfortable in dealing with interdependencies up front. Suggesting refactoring or rewrites can work well in that case.

Re: The Cost of Abstraction (2016)

#27

Structuring 1M line of code as one function or 1M functions is clearly equally absurd. What is the sweet spot? There must be an answer from psychology and/or information theory.

> What is the sweet spot? There must be an answer

Keep things 'square'. This is a fuzzy concept and I don't really know how to explain it properly, other than that the effort spent on each layer of abstraction should be roughly equivalent.

Your example is a single 1m-line function or 1m one-line functions. In this case you probably want 100 functions of 100 lines each (and yes, refactoring like this you probably save 100-fold in overall LoC so it works out.) And your 100 functions are probably nested in a 10-deep hierarchy where they all do roughly the same amount of cognitive work.

Re: The Cost of Abstraction (2016)

#28
post #17

Earlier quoted context omitted.

Which is not to say that we shouldn't wrap dependencies. We absolutely should. But by default, the wrapper should not offer an abstraction that is so flexible that the dependency can be exchanged. Instead, it should start with the actual problem, by offering only abstractions that (a) make sense in the context of the program and (b) translate well to concepts of the dependency/library. For example, hiding POSIX-style…

Dependencies should be treated like if it was your own code. After you have replaced some API for the third time you can start thinking about wrapping it.

> Dependencies should be treated like if it was your own code

Only a Node.js developer could say that. Maybe it's true when the dependency is left-pad or something.

Experienced developers in other languages will acknowledge that (non-trivial) code that is not your own code, is not your own code. You seldom have a very good understanding of the underlying models, and the library has absolutely no understanding of your own model. And it's very hard to make a change in code that is not your own.

Case in point, I just read the title "Linux fsync() issue..." on the HN frontpage. If you have a large project, say a database, I can only hope that you properly abstracted your synchronization model.

Re: The Cost of Abstraction (2016)

#29
Abstractions are of course due when time is right.

It's difficult to address but imo not be the goal from the get go, to introduce abstractions to a codebase.

There is also a cultural thing around abstractions where inexperienced developers look up to or are fascinated with the complexity of something or someone that brings that to the table.

It's also a common feature of certain so called architects, because they probably feel they need to some advanced techniques.

The thing is though, that when you have worked with developers or architects that advocates for simple abstractions, and it over time proves that is both efficient and cheap, then you start to doubt complexity in total.

Also remember that complexity is often not complex per se, as long as you spend time on breaking that complexity down.

And then you have a better fundamental platform for solving what you need to.

Simple code is fast code. And also easier to change.

Re: The Cost of Abstraction (2016)

#30
Lately I've been thinking about the similarities between the abstraction that results from post-hoc software refactoring and post-hoc mathematical proof "refactoring". In both cases the refactoring is an attempt towards a more ideal form, but that form is almost always more impenetrable to newcomers.

E.g., a quote about the mathematician Carl Gauss:

> Gauss' writing style was terse, polished, and devoid of motivation. Abel said, `He is like the fox, who effaces his tracks in the sand with his tail'. Gauss, in defense of his style, said, `no self-respecting architect leaves the scaffolding in place after completing the building'.

Post reply on HN