Live data from Hacker News

How could the early Unix OS comprise so few lines of code?

retrocomputing.stackexchange.com

161–170 of 170 posts

Re: How could the early Unix OS comprise so few lines of code?

#161
post #97

Earlier quoted context omitted.

A classic example of diminishing marginal returns.

Toy solutions deal with small data inputs. How many lines of that 20k is just optimizing for large inputs (you can’t have long repeating sections in small inputs).

My tiny regex in C is complete, in 1K of C. With formal verification

https://github.com/rurban/tiny-regex-c/blob/master/re.c

Re: How could the early Unix OS comprise so few lines of code?

#162
post #9
post #2

Answer: smaller target to cover! Modern Linux has most code in device drivers to support so many different devices. Then, it supports many targets for other subsystems, like file systems. The original Unix provided one implementation for each subsystem. They relentlessly simplified the problem they were solving to make it doable.

Latest Linux kernel source: 39,000 certs 0.0% 40,000 usr 0.0% 164,000 init 0.0% 240,000 virt 0.0% 250,000 ipc 0.0% 459,000 io_uring 0.0% 664,000 rust 0.1% 980,000 samples 0.1% 1,885,000 block 0.1% 2,850,000 scripts 0.2% 2,953,000 security 0.2% 3,609,000 crypto 0.3% 5,165,000 mm 0.4% 7,156,000 lib 0.5% 12,420,000 kernel 1.0% 33,047,000 net 2.5% 39,916,000 include 3.1% 43,224,000 fs 3.3% 45,001,000 sound 3.4% 54,988,00…

FreeRTOS on the other hand is just two C files.

And a proper secure microkernel much less.

Re: How could the early Unix OS comprise so few lines of code?

#163
post #46

It's unsurprising when you consider that there are often several magnitudes of difference in code between what code grows to when you have the capacity and time and compounding user requests, and what a meaningful starting point that provides useful functionality above and beyond what you had without it looks like. As an extreme example here[1] is an article by Brian Kernighan about a basic regexp matcher by Rob Pike…

A classic example of diminishing marginal returns.

It does make one wonder why adding diminishing returns is the usual way of software development.

Proof of concept -> early release -> stable release -> add feature -> add feature -> add feature, ..., repeat.

CPU cycles, RAM use, storage space, bugs, updates, managing complexity, manuals, adapting to newer standards, programmers understanding codebases, etc, etc, etc. It's not like incremental additions are 0-cost.

Kind of like inventory: of all the stuff (most) people have in their homes, only a small fraction is used regularly. The rest only sees use very rarely, or exists for "nice to have", decoration, or plain luggage / junk. Turning free living space into a junk bin, making it more difficult to move house, etc. People who think that junk in their attic costs nothing, can't do math.

The software fix would be to hunt aggressively for ways to simplify, reduce binary size & in-use memory footprint, remove lesser-used features, weigh any feature (present or potentially added) vs. its impact on maintainability, code size, etc.

In other words: maximize the bang-per-byte. Note this does NOT need to mean "feauture starved". Just very capable / useful given its footprint.

As opposed to maximize the feature list, or throw complex algorithms to squeeze every last % of performance.

Any projects out there that have bang-per-byte as #1 priority?

Re: How could the early Unix OS comprise so few lines of code?

#164
post #39

Earlier quoted context omitted.

Reminds me of Mark Twain's quote "I didn't have time to write you a short letter, so I wrote you a long one."

Blaise Pascal originally, I believe. https://quoteinvestigator.com/2012/04/28/shorter-letter/ Great line, though. I use it a lot.

super interesting link! thanks for sharing

Re: How could the early Unix OS comprise so few lines of code?

#165
post #66

Earlier quoted context omitted.

I'm only speaking from impression, but I think early Unix's userland is probably comparable with busybox in terms of code size and features.

I’d be surprised if early Unix userland wasn’t even more barebones than busybox.

It sure was. But so was the kernel itself. I don't think the balance between them changed a lot over time.

Re: How could the early Unix OS comprise so few lines of code?

#166
post #46

It's unsurprising when you consider that there are often several magnitudes of difference in code between what code grows to when you have the capacity and time and compounding user requests, and what a meaningful starting point that provides useful functionality above and beyond what you had without it looks like. As an extreme example here[1] is an article by Brian Kernighan about a basic regexp matcher by Rob Pike…

"I think it's mostly surprising because most developers today aren't used to thinking about capacity constraints of small systems, and so starts designing for lots of features from the start (can't have regexps without character classes, and capture groups, and back-references, and ...)."

Sometimes when I have expressed admiration for sed(1) in the past on HN, someone replies something like, "Yeah, but it doesn't have capture groups."

It is amazing how much work I do with sed(1). Basic RE most of the time, not even Extended RE. And I'm only using a fraction of what sed can do. It is not just me. This small program is everywhere, on every computer. It's in the toolchains used to build the operating systems and other software that everyone is using. The computing world depends on sed.

Then there are people online who complain about RE. With memes, no less. It's baffling to me because I find RE so useful. Eventually I realised the reason they dislike RE is because they want to compose something really complex, they get in over their head and then they try to blame RE instead of ther own stupidity. Meanwhile they could be doing a multitude of simpler things with RE very effectively. But that's not what they want.

Nope. They want the 2000+ lines of code, not the 35.

Of course this is a generalisation. Hence the word "most". There are some who are interested in the 35.

It's really easy to evaluate software today, assuming one is searching for simplicity, because so much of it is garbage written by people who are hopelessly addicted to needless complexity. They cannot define "simple". The mere use of the word is triggering for them.

Re: How could the early Unix OS comprise so few lines of code?

#167
post #75

Earlier quoted context omitted.

May I venture that you're probably early in your career? There's almost always things that can be redesigned to be better and smaller if one has a better understanding of total scope from the beginning, but there's equally as much discovery that the reason things seemed unnecessarily complicated was a lack of understanding of the complexity, and that the new rewrite eventually reintroduces much of it as it's used in…

this isn't always true. more than once I've taken a large codebase, whacked it down to 10% of its original size, without losing any features and gaining quite a bit of performance. smallest-change maintenance by lots of people just introduces cruft by its nature. not suggesting that doing that rewrite is usually a good idea...but I disagree that all that stuff always represents anything fundamental

I didn't say it always does. I said it's about 50/50 on whether the cruft is from actual complexity vs. bitrot.

Re: How could the early Unix OS comprise so few lines of code?

#168
post #46

It's unsurprising when you consider that there are often several magnitudes of difference in code between what code grows to when you have the capacity and time and compounding user requests, and what a meaningful starting point that provides useful functionality above and beyond what you had without it looks like. As an extreme example here[1] is an article by Brian Kernighan about a basic regexp matcher by Rob Pike…

"I think it's mostly surprising because most developers today aren't used to thinking about capacity constraints of small systems, and so starts designing for lots of features from the start (can't have regexps without character classes, and capture groups, and back-references, and ...)." Sometimes when I have expressed admiration for sed(1) in the past on HN, someone replies something like, "Yeah, but it doesn't hav…

Yeah, I think the 35 is probably too simplistic, but as the links elsewhere in this thread shows, you can get an implementation that converts to a DFA and is competitive with your browsers and Nodes native regexp engines in just a couple of times that. I'm not inherently against having options that do crazy work to provide extra features and squeeze out a bit more performance, but I also wish more people would try starting over, because the results are often surprising.

E.g I'm pretty much "by accident" building my own desktop environment. I don't really want to, but I've rewritten bit by bit of software where it turns out rewriting something that does exactly what I want is often simpler than trying to fix issues in huge pieces of software.

It took me one night to replace Caja with my own desktop/ file manager. It does far less than Caja, but it does more of what I want. E.g. it has a semi-spatial mode that lets me control when to snapshot positions rather than do it either always or never.

300 lines of code. Should other people run it? Probably not, but at 300 lines we can afford a lot of variants more closely tailored to different workflows.

My terminal is ca 1000 and close to be more accurate and have more features than st (about 8k lines), and has more of the feature I actually use than xterm (88k lines of code). Xterms scrollbars code is many times the size of my entire terminal.

Xterm is more capable, but not 88 times more capable... And less capable in the areas I care about.

I tend to think we need more software that is less capable.

I'd rather have a wider choice in 1kloc terminals than 1 x 88kloc one, because the 1kloc ones are far easier to customize and tailor.

Re: How could the early Unix OS comprise so few lines of code?

#169

Earlier quoted context omitted.

A classic example of diminishing marginal returns.

It does make one wonder why adding diminishing returns is the usual way of software development. Proof of concept -> early release -> stable release -> add feature -> add feature -> add feature, ..., repeat. CPU cycles, RAM use, storage space, bugs, updates, managing complexity, manuals, adapting to newer standards, programmers understanding codebases, etc, etc, etc. It's not like incremental additions are 0-cost. Ki…

I've come to think we really should be more comfortable forking projects and keeping them small vs. adding features. E.g. consider the space of tiny to small-ish X11 menu tools. There's ratmenu, 9menu, dmenu, rofi, roughly ranged from tiny to slightly on the larger side, and I'm sure many more. If I want to add features to 9menu or ratmenu, I wouldn't add features directly to them unless it's something really minor or very generic. I'd fork them, or rewrite from scratch. Their appeal is that they're small and focused.

I'd rather have a choice of a dozen like them with slightly different feature sets that are easy to customize and tweak for my use, than one big one. Where the cutoff point is varies - I tend to find rofi a bit too big and complex, for example.

Re: How could the early Unix OS comprise so few lines of code?

#170
post #46

It's unsurprising when you consider that there are often several magnitudes of difference in code between what code grows to when you have the capacity and time and compounding user requests, and what a meaningful starting point that provides useful functionality above and beyond what you had without it looks like. As an extreme example here[1] is an article by Brian Kernighan about a basic regexp matcher by Rob Pike…

I think the “never look back” mindset of product growth is a major driver of code bloat.

Rarely are engineering teams allowed time to go back and refine and optimize legacy code, until it’s a blazing dumpster fire… and even then.

Products never seem to have enough features, so engineering teams plow forward. When a component absolutely needs a rewrite, the rewrite is often implemented with the same haste as the original.

Given the time, I think every engineer could easily factor out vast swaths of code and refine what’s left to be much leaner.

I feel like the same goes for programming languages and platforms. Most devs would prefer to spend their time adding new capabilities rather than optimizing a few lines of code out of existing ones.

But then again “Perfect is the enemy of good” and “If it ain’t broke don’t fix it” and “We’ve got 731 items on the roadmap, so let’s go!”

Post reply on HN