I've spent literally years pondering this. And then I forgot most of it.
Plan 9 gets an amazing amount done with astonishingly little code. The joke is "90% of the code implements externally-imposed standards." There's a lot of truth in that. It's far more powerful than xv6. For scripting tasks involving multiple machines, especially on a LAN, it's vastly more powerful than POSIX and yet much smaller and simpler than even a basic POSIX standard OS.
But...
iansjack wrote:I suspect that the projects that you are looking at are more developed, support a wider range of systems, and are more robust than yours.
After about 5 years of full-time Plan 9 use, I had to conclude there's a lot of truth in this viewpoint, particularly the "more developed" part. Plan 9 does a suprising range of things, but I always found myself bumping into limits and awkward artefacts which I have to say result from trying to get too much out of too little code. More complex systems are often more comfortable. One huge example of such artefacts was excessive use of private namespaces to simplify the code. For instance, the kernel had no means of multiplexing the console between processes. The window manager, Rio, did it instead, using private namespaces to present a different virtualized /dev/cons in each window. Ditto for /dev/mouse. This means you can't simply mount a disk or service in one window and have it accessible in others. 9front supports a workaround, but any workaround is more code and, like so many other things in Plan 9, it requires yet more code (in the form of sophisticated scripting at the very least) if you want more than the minimum use out of it. "Plan 9 is not meant for non-programmers."
I am not, however, trying to excuse systems which are complex merely due to a lack of understanding or clarity of thought. Some of Plan 9's simplifactions
may have been genuine all-round improvements which the computing world is worse off for not adopting, but I'm not entirely in a position to evaluate them.
nullplan wrote:My best guesses are: Bugfixing and lack of proper design. Bugfixing (especially in a badly designed program) can often take the form of adding code to handle a specific case, rather than modifying code such that wrong assumptions are not made. This is usually effective (sadly), and so if a rotten codebase is left to stew a bit, it will grow all these case distinctions that are all necessary (because without them, the code is buggy), but that ultimately stem from a failure to properly model the problem in the first place.
That's a lack of refactoring, or just "factoring" if it's Forth. It is a somewhat common problem but probably much less than it was not the importance of refactoring is understood. Charles Moore was promoting factoring in 1970 and onward, (and I don't suppose he invented the concept,) but I don't think the majority of programmers started taking it seriously until the '00s, maybe even the late 00s. No doubt the "agile programming" fad made programmers conscious of it. (Half of agile programming came straight from Forth good practice.)
nullplan wrote:Or maybe I'm just cranky because I just got off work, fixing a codebase that grew to enormous proportions due to lack of overarching design. I threw out 1000 lines of code today. I would quote Ken Thompson here, but I find myself throwing out 1000 lines of code so often, I'm wondering if I'm that good or the code is just that bad.
The code is massively overdue for refactoring and may have been the product of confused minds in the first place.
Some people have trouble expressing themselves clearly and concisely. I quite expect they also have trouble writing clear, concise code. (Incidentally, I
factored those two sentences before even finishing them.
Some days I'm good at factoring my posts. Other days not so much. Today is in-between.) In any case, I'm sure what you're doing counts as [re]factoring.
Sometimes, code bloat is due to bad dependencies, in which you could include languages like Java which require a lot of boilerplate. A friend who hates code bloat interned at a tech company and later went to work there. While interning, he wrote a 500-line utility and couldn't figure out how to integrate it into the build system, so he wrote a 10-line makefile. When he returned to work there the next year, he found someone had written a
150 line file to integrate it into their build system. In other words, the build script for this little utility had gone from 2% to 30% of the size of the utility itself!