I actually attended the talk this is from, the concept of recipe writers vs abstractioners is not aimed at the actual developers but at the tools and how they are developed. His idea is that the tools should be built around aiding developers in their need to abstract the data (Bret Victor talked a lot about this as well).
I'm not objecting to abstractions at all. I'm just advocating understanding the fundamentals first.
I want to use abstractions and tools where they offer an additional benefit, but without being limited to whatever some predetermined choice of tools or abstractions can do.
There's probably two sets of people at work in the statement.
The people who made the frameworks would require a good understand as well as the idea that an abstraction might make life easier.
The side effect is that if you create a good enough abstraction you'll get people who can handle the abstraction but are a little shakey when dealing with what is abstracted.
I don't think abstraction is even the right concept to be talking about here. Being able to work with an abstraction doesn't imply ignorance of the details, and ultimately the best code comes from people who know how to make abstractions that are elegant and aren't leaky (which takes expertise in both domains).
This is a great point. For me it isn't poetic at all, but a deductible consequence.
If our job is creating abstractions it must be really hard to create tools which abstract properly our job. Where abstract properly would be separating what is really our job, the abstractions we are creating, and what are the trivial abstractions, the ones we assume as stable. This is a hard path to reach any usefull conclusions or insights to develop new programming tool features. The separation from what are the abstractions we're creating and the abstractions we're building on top off is always changing and it's in the same place (in the code).
For reaching usefull conclusions I would rather think in the different tasks developers need to pursue. Who wants to build a RescueTimeesque tool for developers?
Lisp, with his code is data super-feature, and his REPL super-environment has a lot to say in this two issues.
Right: phrased differently, weaker abstraction power means recurring problems have to be addressed by documenting patterns with fill-in-the-blanks recipes, instead of reusable code libraries.
> Aren't ability to abstract and experience sort of similar?
No. They are distinguishable from each other. One may feed the other, but they are separate.
> I don't really consider the ability to write a generic function (instead of copy-paste) to be the same as the ability to abstract. To write a good abstraction you need to understand both the underlying system and the consumption pattern to avoid abstraction leaks, boilerplate, hiding of useful features, etc.
You are confusing abstraction with data and function hiding. In the article abstraction means the ability to meta program, translate one problem into a simpler generic problem, etc. This is a skill most of the industry lacks _in practice_. It is a skill that all 1% coders have, but it also doesn't make experience go out the window.
It's not so much scientists vs. programmers, it's more about experience.
If you write a lot of software, hopefully you're getting better at it, learning new skills, applying that, etc. It's like abstraction is like calculus if you know it it greatly simplifies things, if you don't it mystifies things.
More experienced software writers generally write at a higher level of abstraction.
I think that Yossi's point was the the non-programmer writes at a very low level of abstraction and this is a great virtue. Although there is a great deal of nuance to this debate I fall more and more on his side of it.
I think that one of the biggest problems with this debate are the numerous examples of exceptionally powerful and useful abstractions we used every day.
Programming languages are a wonderful abstraction over assembly which is a marvelous abstraction over machine code. Compilers leverage this abstraction to produce exceptionally fast machine code that few humans could ever match.
The file system is a fantastic abstraction over a broad range of very complex storage medium, you can even pretend a hard drive on another computer is part of your local file system.
So abstraction is clearly the most powerful tool in our toolbox. It's what allows us to climb above the Roman Numerals of computing.
I think the thing that is lost in this debate is the number of failed abstractions. Each of the abstractions listed above were hard won and are painstakingly maintained by dedicated developers. Even within their ranks there are countless failed examples, file systems that were unreliable and programming languages that made life harder than it needed to be. The other feature of those abstractions listed above is that there are few of them and we spend a large amount of time learning about them. As a Java developer I have invested a significant amount of time learning the details of Java garbage collections. Now there is a wonderful abstraction, that has some sharp spikey corner cases.
We can look at some common abstractions, third party libraries. I will use Spring as an example. The list of abstractions explodes, each one appears unique and I know developers who swear by Spring and use it extensively and who struggle to answer concrete questions about it. Vast quantities of unreliable and very hard to read code has been built on top these kinds of abstractions. (I note reluctantly that plenty of reliable software has been built on top of Spring too, and there are developers who have a very good grasp of at least some of it).
Finally lets survey a final category of abstraction. The ad hoc per project abstraction. This is what Yossi is actually talking about in his article. In enterprise Java these are typically a swirling mass of classes whose names are concatenations of various design patterns. These are typically of a very low quality, the programmer who wrote them had deadlines and has since moved on. They are 100% unfamiliar, they are 100% awkward and, like a man lost in the desert desperate for a drink of water, I find myself yearning for a concrete instantiation and a plain old method call.
My personal feeling is that, yes abstractions are extraordinarily powerful, but only when they are good and only when we understand them. I think producing new and useful ones is always harder than we expect. It's good to remember that we didn't replace roman numerals with ten thousand unique numeral systems.
We are getting more abstractions, not necessarily better ones. I much prefer working with people who figure out how things work under abstractions rather than relying on them blindly.
All good points, however Bret Victor has specifically been showing off alternatives to low level programming by building very high levels of abstraction. He has even apparently said that he thinks the development community is purposely keeping programming complicated to maintain the demand for their specialized skills. I think the law of leaky abstractions is why it is simply not possible to elevate programming to a level of abstraction that allows people without specialized skills to implement arbitrary applications.
> 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.
I'm not decrying abstractions. I am the biggest proponent of abstractions on the planet.
What I disagree with is the tendency to use the same monstrous framework for every project, regardless of size, scope, and purpose.
And part of my complaint is that the abstractions don't always abstract anything. Some of them just rename things for the sake of style. That may or may not be a bad thing, but I don't think the average developer even gives this any consideration. If anything, the fact that you're passionate enough to actually leave a comment about the article generally points to the fact that you're not one of the people that needs to hear this sort of lesson. :D
They do? In my experience, lack of abstraction (often due to not analyzing the issue at hand thoroughly) results in non-abstract, verbose, hard to understand and refactor code. It's the difference between, say, building an SQL query by appending strings to a buffer (move one line and everything blows up) and building a model of your query (projection, etc...). Sure, the abstraction means more code, but it's much more easier to manipulate and considerably less risk-prone. It won't be faster than doing it the other way, but it won't be necessarily measurably slower.
I love this book. At the same time, isn't the whole point of abstraction to make this knowledge irrelevant for people who build applications on top of it? Like, the knowledge should only have utility insofar as the abstraction designers and implementers at the levels below yours did a bad job, unless you have a use case they didn't design for
reply