Logic that the blog presents is sound; but sometimes small works as a good-enough proxy to get to the simplicity that we find elegant.
Simple Is Not Small
51–60 of 95 posts
Re: Simple Is Not Small
#52> There's no native Unix equivalent to frequencies, this sort | uniq -c is the closest we can get. Not only is it less performant (it has to collect the full input into memory before continuing), but it ties aggregation to ordering. One of the core features of the Unix command-line is that it is user-extensible. If there's no "native" command equivalent to frequencies, you can write your own, and it will be given the…
awk '{ freq[$0] += 1 } END { for (n in freq ){ print freq[n] " " n } }' < file.txt
Re: Simple Is Not Small
#53> There's no native Unix equivalent to frequencies, this sort | uniq -c is the closest we can get. Not only is it less performant (it has to collect the full input into memory before continuing), but it ties aggregation to ordering. One of the core features of the Unix command-line is that it is user-extensible. If there's no "native" command equivalent to frequencies, you can write your own, and it will be given the…
Yeah, that point was weak. The argument went from "Unix pipelines are not simple" to "unix based operating systems don't have an equivalent to Clojure's frequency function by default so it's worse" OK but how would it look like if you had such a program? Shells are not known for having the extensive set of functions that real programming languages have.
That said having key/value semantics and not just stream of bytes would make the shell much more versatile, at the cost of making it bigger.
Re: Simple Is Not Small
#54Strong resonance with the famous essay "The Rise of Worse is Better" [1], which contrasted the (better) "MIT/Stanford style of design" with the (worse) "New Jersey approach". MIT/Stanford: > Simplicity -- the design must be simple, both in implementation and interface. It is more important for the interface to be simple than the implementation. New Jersey: > Simplicity -- the design must be simple, both in implementa…
Re: Simple Is Not Small
#55The clojure expression reads the entire file into memory first, and then operates on that memory representation.
The pipeline processes the input in chunks. The two `sort`s might read the entire contents into memory, but an implementation like GNU sort will instead, for large inputs, create temporary files for sections of the input and then merge sort them to the output.
You could make clojure do the same thing, but it might not be as "simple" as the pipeline.
Re: Simple Is Not Small
#56> Unix pipelines are not simple But they are. UNIX Pipes do not mandate having to use tons of different programs with stupid commandline options. I simulate them in ruby itself; method chaining works in a very similar way, but I built a pseudo pipe around it. The idea was more to have an object oriented shell, e. g. combine good ideas from UNIX pipes and the MS powershell. They are simple if you design them well and…
Did you remember to:
- check for the other spawned process exit code?
- waitpid for all process in the other process chain?
- propagate/handle signals, like for example SIGINT/SIGTSTP/SIGPIPE/SIGHUP forward and back signals?
- change stdio buffering mode?
- remember to count how many bytes actually were written by write, and blocking if not, before clobbing the 64kb of the pipe buffer size with another write?
- flush, then close all file descriptors left behind by the pipes when it ends?
It's for reasons like that, that I don't trust anything non-trivial, not-shell to use pipelines correctly.
Re: Simple Is Not Small
#57"In Clojure this is fairly straightforward" Somehow when things get complex, I could never find fully functional style to be more understandable than imperative
Re: Simple Is Not Small
#58Another solution to the pipeline example, this time making use of a subprogram for the frequency/accumulation: If you don't allow `awk` in your "pure bash" then ofc this is not satisfactory. But it has the upside that the associative arrays are pretty explicit data structures (for the ordering and counts, respectively).
Nice to see more people getting nerdsniped by the sh code. ;-) Yes, associative arrays work well. I think it should even be possible to use bash associative arrays. But at that point you're no longer doing classic sh - awk is basically halfway to Perl. (And pretty awesome.)
Without processes shell is just a weird sad little language, with them it turns into this epic data flow language. With some real design stinkers, Most of these are due to it's interactive first focus, The features desirable for interactive use, often start to stink for stored program use, I will note that having the same language for interactive and scripting is pretty kick ass.
On the subject of dataflow languages has there been any research in this area? Something that can stitch together processes as well or better than shell? Perl may work in this role but I have to admit I really dislike it's syntax, and as such I never learned Perl enough to love it. and while most other scripting languages can technicaly create pipelines, it is very awkward compared to shell.
Re: Simple Is Not Small
#59Earlier quoted context omitted.
Yeah, that point was weak. The argument went from "Unix pipelines are not simple" to "unix based operating systems don't have an equivalent to Clojure's frequency function by default so it's worse" OK but how would it look like if you had such a program? Shells are not known for having the extensive set of functions that real programming languages have.
I think the point was more that it's hard to compose shell utilities to make something new that's not supported out of the box. Instead you do have to write an entirely new utility and use that. That said having key/value semantics and not just stream of bytes would make the shell much more versatile, at the cost of making it bigger.
All of this is completely correct, but it has nothing to do with bash vs. Clojure. The same decoupling can easily be achieved in either language.
Re: Simple Is Not Small
#60Strong resonance with the famous essay "The Rise of Worse is Better" [1], which contrasted the (better) "MIT/Stanford style of design" with the (worse) "New Jersey approach". MIT/Stanford: > Simplicity -- the design must be simple, both in implementation and interface. It is more important for the interface to be simple than the implementation. New Jersey: > Simplicity -- the design must be simple, both in implementa…
I appreciate the New Jersey simplicity as a user (with development skills) too, though. It's usually just a matter of time before I have to dive into the program/library/whatever internals to fix a bug.
Sorry, I meant Microsoft Copilot 365.