Skip to content

Comment on Simple Is Not Small

Comments

The post is mixing up a lot of stuff because of a category error: conflating system design (pipelines) with language design (Clojure and Bash).

The Unix pipeline and the similar-looking Clojure expression are entirely different in how they do what they do. Pipes are process abstractions. The (perniciously improperly understood) "pipeline" macro is not pipelining anything in any way (not CPU nor process nor memory). It is merely syntax sugar to write a deeply nested call chain as a "flat" list of operations.

And it goes on to compare "ugly" code, again making the category error that "more" code is "worse". Because, one is swapping / splicing entire programs within a pipeline. Also, there are plenty of ways to slice that mango; you don't need temp files.

That said, having intermediate files in one's pipeline is a big help because one can use those to make pipelines idempotent. Plus, one doesn't need flat files, one could swap in a SQLite cache too, at will, without modifying anything else in the pipeline. This kind of design change is not possible with the equivalent Clojure function call chain, as-is. In fact, having such a requirement (one always finds need to restart processes after crashes, and have them pick up from where they died) causes us to write some custom (and therefore design-wise brittle) conditional restart loop on top of the computation to manage its failures inside the running program. An idempotent Unix pipeline simply needs to be... restarted from outside the process.

In this particular case, a valid complexity complaint would be about the lacunae of the Bash / shell programming language (and interpreter model) versus the Clojure language.

Also, again from a program design point of view, I feel there's a bit of "holding it wrong" going on there... Bash / Shell-fu, yes, but not enough to be dangerous (for example, sort | uniq | sort is a standard idiom of pipeline programming). Which claim is personal, and so I'm open to being corrected at the same level. Sources: my code and writing:

https://www.evalapply.org/tags/bash/

https://www.evalapply.org/tags/clojure/

https://github.com/adityaathalye (the pinned repos are Bash and Clojure)

And specifically, this log processing code, for a more apples-to-apples comparison with OP's post.

https://github.com/adityaathalye/bash-toolkit/blob/master/lo...

  deduplicate() {}

  frequencies() {}

  drop_first_n() {}

  drop_last_n() {}

  drop_header_footer() {
     drop_first_n "${1}" |
         drop_last_n "${2}"
  }

  window_from_to_lines() {}
(edit: some clarifications, and references)
AboutSource Built by g1lg1l

Hackerly is an independent reader for Hacker News, built on the public HN API. Not affiliated with Y Combinator.