People really mean different things when they say "simple".
For someone it may be "the abstraction is so clean, small and self-contained that I don't have to look at the implementation", for others "the implementation is so clean, small and self-contained that I don't need any abstraction". The author of this post clearly subscribes to the latter philosophy.
I guess many flamewars on mailing lists ultimately boil down to this culture clash.
The best designs have both clean abstractions and small/simple implementations.
If you have a clean abstraction but a complicated implementation, then there are probably lots of moving parts and sub-steps that can go wrong. No user is completely isolated from implementation: take shell completions for example. Shell completions are this nice simple interface -- push "TAB" and the shell will help you out if it can. But because there is so much machinery going on in the background, a slow or unavailable NFS volume (for example) can make your completion suddenly grind to a halt, even if you don't care about that NFS volume right now.
What Richard is talking about in this example is having as little extraneous stuff going on as possible. The fewer moving parts, configuration files, commands you have to run, etc. the less there is to understand, the fewer states the entire system can be in, and the fewer sub-steps there are that can go wrong.
The hallmark of a truly great abstraction is that it gives you the functionality you need without getting in your way, and that higher-level abstractions can be layered on top without the lower-level abstraction getting in the way.
It is not widely known that you can have both clean abstractions with simple implementations.
At the Viewpoint Research Institute[1] (co-founded by Alan Kay), they are trying to have their cake, give it to everyone, and eat it too[2]. They already have some successes, with for instance a set of several programming languages that can implement itself, from bare-bones X86 to sky-high abstraction, in less than 1500 lines; a TCP stack that takes 200 more lines (a 50 fold reduction compared to a typical C implementation); and more.
Efficiency wasn't even the priority. But as it turned out, many optimizations were either very generic (across several languages), or plain unnecessary (some things are faster than anticipated, to the point of being good enough).
There is, ultimately, a direct conflict between abstraction and efficiency. Abstraction gets its power by using indirection: generalizations that stand in for specific cases. Making abstractions concrete involves a flattening of all these indirections. But there's a limit on our ability to automate the manipulation of symbols - we don't have Strong AI that is able to make the leaps of insight across abstraction levels necessary to do the dirty hackish work of low-level optimization. The fabled "sufficiently smart compiler" doesn't exist, and is unlikely to until we have Strong AI.
I'll further submit that a design that has clean abstractions and simple and small implementations either doesn't do much to the point that it's not very useful on its own, or if it is useful the complexity has moved somewhere else, perhaps in metadata or configuration or tooling. It's like there's a law of conservation of complexity; there is a certain amount of irreducible complexity in useful programs that cannot be removed, and remains after all accidental complexity has been eliminated.
Seeing http://vpri.org/html/work/ifnct.htm I think we have good reasons to believe that we currently are several orders of magnitude above that amount of irreducible complexity.
So, while I mostly agree with what you just said, I don't think we've hit the bottom yet. Silver bullet-like progress still look possible.
No, the dichotomy is better described as r-selection (worse-is-better) versus K-selection (the right thing)[0].
For a practical example of worse-is-better software becoming popular, look at the World Wide Web in relationship to Project Xanadu[1]. For a practical example of The Right Thing software being popular, look at Python. The argument is broadly that New Jersey worse-is-better produces software more likely to become successful than the MIT right-thing approach. That doesn't mean that worse-is-better is always more successful, or that the MIT approach can't produce successful software, or that there's not a time and/or place for both approaches.
No, I don't think that captures the ideas in Richard Gabriel's essays. Simple vs. The Right Thing are the two sides, where the right thing is a complete and polished piece of software full of features, what a typical young engineer would create if given lots of time and resources to do things "the right way".
I think he calls it "worse" as a way of emphasizing that e better course of action may not feel fully responsible, as in the PC-losering example.
It's mentioned in the paper "EROS: a fast capability system" (http://www.eros-os.org/papers/sosp99-eros-preprint.ps): they write "This design is similar to that adopted in Fluke and MIT’s ITS system" and cite the ITS reference manual for the latter.
(I remembered reading that paragraph since before that I had only ever seen the technique mentioned in Gabriel's essay :) ).
Well, my point is this: If only three or four OSes have ever implemented it, none of which have been very successful, how important could it possibly be? Do other OSes have ways of making the problem irrelevant without actually fixing it like ITS, Fluke, and EROS did?
For someone it may be "the abstraction is so clean, small and self-contained that I don't have to look at the implementation", for others "the implementation is so clean, small and self-contained that I don't need any abstraction". The author of this post clearly subscribes to the latter philosophy.
I guess many flamewars on mailing lists ultimately boil down to this culture clash.