3 ms·
I’m fairly conflicted by this, because it’s fairly insightful, but it’s also probably overselling itself. They expound quite hard on the idea that abstraction
by jchw 5y ago
I’m fairly conflicted by this, because it’s fairly insightful, but it’s also probably overselling itself.
They expound quite hard on the idea that abstraction is inherently bad, and I feel this is a poor choice of words, and perhaps a mistake. Abstractions have cost. In many forms, and especially if the abstraction is a poor one.
However… they don’t seem to differentiate between good and bad abstractions. They seem to regard all abstraction as simply unnecessary, only used because our brains cannot deal with the entire problem at once.
I think you could make this argument to some degree but it breaks down when you start to see where abstraction is worth the cost. As an example, let’s say I’m writing a service that needs a key value store. If I make a simple abstraction for it, with well-defined properties for exactly how it should behave, how data consistency should work, etc. then implement multiple backends, this is a good abstraction. The reason for this is because software doesn’t have fixed requirements. Some users may be running a small instance of something on their desktop or a NAS or what have you, whereas others may be running software on gigantic clusters and would benefit from using clustered key value stores that are much more difficult to setup for valid, unchangeable reasons, even if we were to get rid of the abstraction and fully integrate a distributed key-value store right into our program.
Also, requirements change temporally. Clang could’ve implemented everything with no abstractions, but when Clang was created it targeted older and fewer versions of programming languages. The abstractions have cost, particularly when they are bad; but not having abstractions would’ve costed far more, IMO. Extending and reusing software that has little abstraction is very difficult because there’s very few reliable boundaries you can work off of. Adding a new operator in Clang is probably still hard, but I’m sure it would be harder if you carried forward all of the abstraction and folded it down instead. You need some kind of abstraction if you want cheap extensibility.
So my conclusion is basically, abstraction is not bad. Libraries are not bad. Engines are not bad. They simply have costs that are not accounted for properly, and may cost more than the value they provide in many cases. Intuitively, we know this; It’s basically the knee-jerk software engineers get when they get into a build-vs-buy discussion. You feel the jolt. The library has an amazing feature list, but something tells you it won’t be so easy. That’s the hidden cost right there.
- chii 5y ago> You need some kind of abstraction if you want cheap extensibility. so does the need for cheap extensibility comes first, in which case you build up the abstraction to enable it? Or does abstraction get built up first, which gives you cheap extensibility, then users start needing it afterwards? What if clang didn't end up being as popular as it did, and the effort it took for the "cheap" extensibility was never needed as no one actually extended it?
- jchw 5y agoIt’s usually non-trivial to add later, so you have no choice but to essentially make a guess and hope it’s right. There’s basically no real alternative. Of course, if it is trivial to defer an abstraction until later, then it’s better to do that. But it is almost definitely not for Clang operators, which cross cut almost every distinct unit of the program (lexing, parsing, etc.) (This is also referenced at some point in the talk itself, though I can’t remember exactly where, but my take is that you can’t really fully understand the ideal architecture to solve a problem before trying to solve it, and in trying to solve it you must make architectural decisions.)
- xelxebar 5y ago> They seem to regard all abstraction as simply unnecessary... I would be surprised if the video author agreed with this statement. My understanding of his point is something more general and almost trivially true, i.e. a given set of abstractions can't solve problems the same way as a different set of abstractions. The strong version is a Venn diagram ┌──────────────────────────────┐ │ │ │ Implementations expressable │ │ by abstraction set A │ │ │ │ ┌──────────────────────┼───────┐ │ │ │ │ │ │ Implementations │ │ │ │ expressable by both │ │ │ │ │ │ └───────┼──────────────────────┘ │ │ Implementations expressable │ │ by abstraction set B │ │ │ └──────────────────────────────┘ In particular, if you are still in the "this problem isn't completely, rigorously nailed down" phase, then building abstraction-hierarchy A implicitly means that you cannot explore some of the solutions available to abstraction-hierarchy B. Said another way, abstractions cut down the space of possible solutions. Cutting down the space definitely has large upsides. If you're trying to build a nuclear plant, we probably want to weed out the cake-baking solutions. For especially large and complex problems with horrendously large solutions spaces, abstractions function as a way of compartmentalizing some of that solution space into manageable sub-problems. However, maybe there is a better set of sub-problems? After a year hammering on some software development project, you probably have a much clearer idea of the problem's nuances than when first starting. Wouldn't it be great if we could perform low-cost rewrites? If you can hold the entire source code in your head and cognate about it, that's probably even possible. Could any one human hold all of Firefox in their head? One point from the video stands out to me: abstractions might just be a necessary evil. They are effective tools for helping humans cognate about complex problems, which involves limiting our ability to cognate about potential solutions. Anyway, I am reminded of the surprising solutions found by genetic algorithms and their ilk.