Live data from Hacker News

Kernighan and Pike were right: Do one thing, and do it well

medium.com

31–40 of 256 posts

Re: Kernighan and Pike were right: Do one thing, and do it well

#31

Good article, but to me it seems to be co-opting the term enshitification in a strange way: > Large codebases will eventually reach an “enshittification point” — the point at which bugs are introduced faster than they can reasonably be fixed. I think of enshitification primarily as an organisational/business phenomenon rather than a technical one. It doesn’t necessarily emerge “bottom up” as the result of technical d…

Suggestions for a term for the phenomena?

Emshitifaction?

Re: Kernighan and Pike were right: Do one thing, and do it well

#32

  To count the number of functions in a rust file you could run:

   cat main.rs | grep "^\s*fn\s" | wc -l
This both promotes the "one thing well" model, while revealing its inherent limitations.

How many functions are in this rust file?

  /* confuse things
  fn fo fp
  fn fm fl
  */
  fn
  main() {
      println!("Hello, world!");
  }
The above grep reports two, when there is only one.

It can be made to work if everyone agrees to follow conventions, like always formatting the Rust code, and indenting comments which look like Rust code.

But that means pushing complexity onto people, rather than into the tools. Which you could do at the beginning, when complexity is low, but it gets increasingly more difficult over time.

Re: Kernighan and Pike were right: Do one thing, and do it well

#33

The basic point is right, but I think a lot of the details are off. The core idea is composition. A system is compositional if you can build it from small reusable parts. It's one of the key ideas in functional programming, and it's somewhat core to object-oriented programming. (OO is too big to be able to claim their is a consistent philosophy behind it.) But ... firstly, let's stop with the Unix worship. They didn'…

Let's just be careful what we call Unix though. In SVR4, I don't think "ls" had that many options. It didn't even have colour (not that I would know; my Wyse 60 could only have Green, Orange or White text... and the colour was set in the factory). It's the same for many programs that started small but grew loads of knobs with age. You can't claim that this was the Unix vision, because what we call Unix today isn't ev…

It's still a failing of the Unix philosophy that people found it easier to add all these flags to ls than to string together a few "simple&composable" commands.

Re: Kernighan and Pike were right: Do one thing, and do it well

#34

These tools are not composable once you venture outside of a shell, and if I have to write anything beyond 5 lines, I'm not using one. There needs to be a way to make these applications usable as software libraries, and no, invoking them as a separate process from the main application does not count. This is the reason the functionality of these tools have been reinvented many times over and why they get extra cruft…

> invoking them as a separate process from the main application does not count Why not? What is your worry? That starting a process is too slow? That data transfer is too slow? Something else? I agree that process startup may be meaningful overhead in the rare cases when the actual computation is very fast. But sharing uncompressed data between programs is essentially zero-cost. Separate processes look particularly e…

I agree 100% with using processes as the natural unit of isolation.

I also believe we could solve many of the integration issues between multiple tools, by having them all optionally spit out a universal, easy / easier to parse format -- even JSON would be good here. So you could do

  ls --foo --bar --json | jq ...
and be able to process the output to your heart's content, without having to do any kind of white space parsing; as a free bonus, you get automatic support for file names with embedded white space...

The best we have for now is jc (https://kellyjonbrazil.github.io/jc/), which knows how to do this for a closed (but growing?) set of commands:

  ls -l *.db | jc --ls | jq .

Re: Kernighan and Pike were right: Do one thing, and do it well

#35

Earlier quoted context omitted.

Let's just be careful what we call Unix though. In SVR4, I don't think "ls" had that many options. It didn't even have colour (not that I would know; my Wyse 60 could only have Green, Orange or White text... and the colour was set in the factory). It's the same for many programs that started small but grew loads of knobs with age. You can't claim that this was the Unix vision, because what we call Unix today isn't ev…

IMO the problem with the Unix model is not that it's been corrupted over time, but that it was fundamentally flawed from the start. I'm hardly the first to point this out, but sending around unstructured text makes doing some things inordinately hard (imagine writing a separate program to color ls's output, instead of having that as a flag) + going beyond pipes leads to the awful experience of programming in shell.

Ls seems like a bad example.

Anything that you'd want to colour, the data should already be there.

Further I'm not sure the Unix way inherently requires completely unstructured text

Re: Kernighan and Pike were right: Do one thing, and do it well

#36

Its an insightful read and the final graph analogy seems very apposite. But here is the rub: if microservices is a general graph pattern, it includes all the other patterns (likear, hub and spoke etc) as these are all just particular graphs. In other words, you could implememt unix pipe like or plugin like microservices by applying certain constraints.

Right, but implementing a restricted domain (pipes) with tools designed for a more general domain (graphs), gives up the efficiencies and reduced complexity of the restricted domain. That is why we have restricted domains.

The efficiency argument depends a bit on the scope one considers. If you only ever need pipes it makes sense to optimize and learn how to build pipes and your toolkit will reflect that. But if you need a variety of patterns you need to weigh in the inefficiency and cost of switching. The analogy would be a multi-purpose tool versus many special purpose ones (and the knowledge of operating each).

This is all theoretical ofcourse, but my sense is that the debate about microservices is colored first of all by the extra complexity of networked computation (which raises the bar for a succesful architecture) and maybe indeed the absence of well defined constraints that would guide people on different possible best practices for segmenting monoliths.

Re: Kernighan and Pike were right: Do one thing, and do it well

#37
I wish people would stop applying the "only do one thing and do it well" to all software. Kernighan/Pike were explicitly talking about software tools in the Unix environment, not about all software in general. It is an idealist, you might even say elitist view of how software should work, which they then realized in Plan9. And as impressive as Plan9 is, there's a reason it never got widespread adoption, and that is not just because of evil Microsoft/IBM/whatever. It simply did not solve the problems people had, because it did not run the software the people (which are mostly non-programmers) actually needed to do their daily work. Yes, you can use these systems to write shell primitives, yet another build system, a window manager, a Wiki system, a basic text editor - mostly tools for programmers. It's like people with 3D printers mostly printing stuff to improve their 3D printer.

Re: Kernighan and Pike were right: Do one thing, and do it well

#39
post #31

Good article, but to me it seems to be co-opting the term enshitification in a strange way: > Large codebases will eventually reach an “enshittification point” — the point at which bugs are introduced faster than they can reasonably be fixed. I think of enshitification primarily as an organisational/business phenomenon rather than a technical one. It doesn’t necessarily emerge “bottom up” as the result of technical d…

Suggestions for a term for the phenomena? Emshitifaction?

The article could have used the term technical debt. To me technical debt happens not only when new code gets added in a sloppy way, but also when the developer experience gets worse.

Re: Kernighan and Pike were right: Do one thing, and do it well

#40

These tools are not composable once you venture outside of a shell, and if I have to write anything beyond 5 lines, I'm not using one. There needs to be a way to make these applications usable as software libraries, and no, invoking them as a separate process from the main application does not count. This is the reason the functionality of these tools have been reinvented many times over and why they get extra cruft…

> invoking them as a separate process from the main application does not count Why not? What is your worry? That starting a process is too slow? That data transfer is too slow? Something else? I agree that process startup may be meaningful overhead in the rare cases when the actual computation is very fast. But sharing uncompressed data between programs is essentially zero-cost. Separate processes look particularly e…

As someone who writes software that does a lot of this:

Process management gets very annoying, very quickly. When you run a helper program soon you have to consider process management. What if it crashes? What if it gets stuck? What if you crash and it remains running? What if the user uses the same program elsewhere? None of this gets work done.

A text stream is an awful API. Many times the called program doesn't intend to provide an API, or doesn't commit to stability. Your code breaks because version 5.0.2 fixed a typo, and you relied on the typo for your parsing.

A text stream is an awful API. Instead of a nice protocol you get to parse lots of text, deal with escaping and quoting. You better hope the called program does it competently. It may well not, then you have a problem.

A text stream is an awful API. No normal program will dump or read a JPEG over stdin/stdout, so if you need to communicate some sort of binary data now you need another communication channel. That may involve commandline arguments, killing, restarting the program, and reestablishing the state. More process management fun.

A text stream is an awful API. You'll find yourself doing things like assembling multiple lines of output into a single coherent concept, and trying to detect where something ends when the program doesn't necessarily provide a clear indication.

A text stream is an awful API. Sometimes programs print stuff before it took effect, and may not ever give you a clear indication of "now it's been applied". You may need to somehow test for it, retry operations, insert wait states.

99% of the effort invested in this doesn't get work done. You're spending it on management that wouldn't exist if you were using a sane API like DBus or similar, where you don't deal with process management, where things are broken down into nice fields, and where the API is intended as an API.

Post reply on HN