September 5th, 2024

Shell Has a Forth-Like Quality (2017)

The blog post compares the Unix shell's Forth-like qualities and higher-order programming with systemd's role in Linux boot processes, advocating for an improved shell while favoring daemontools' modular design.

Read original articleLink Icon
Shell Has a Forth-Like Quality (2017)

The blog post discusses the unique qualities of the Unix shell, particularly its Forth-like characteristics in terms of function composition and higher-order programming. It contrasts the shell's capabilities with systemd, which aims to replace shell scripts in Linux boot processes. The author argues that the shell can achieve higher abstraction levels through functions like "retry," which demonstrates the shell's ability to treat code as data. The post also highlights the concept of Bernstein chaining, used in daemontools and qmail, which emphasizes modular design and the principle of least privilege. The author expresses a preference for daemontools' approach over systemd's, acknowledging the criticisms of shell scripts while advocating for an improved shell that retains its architectural strengths. The conclusion suggests that while systemd has its merits, a refined shell could address existing issues without necessitating a complete shift to a Lisp-like configuration system.

- The Unix shell exhibits Forth-like qualities in function composition and higher-order programming.

- The author contrasts the shell with systemd, which seeks to replace shell scripts in Linux.

- Bernstein chaining is highlighted as a modular design principle used in daemontools.

- The author favors daemontools' approach over systemd, despite acknowledging the limitations of shell scripts.

- An improved shell could address existing syntax issues while preserving its core architectural characteristics.

Link Icon 4 comments
By @wwfn - 5 months
from the linked art of programming[0]

> Bernstein chaining is a specialized security-wrapper technique invented by Daniel J. Bernstein, who has used it in a number of his packages. Conceptually, a Bernstein chain is like a pipeline, but each successive stage replaces the previous one rather than running concurrently with it.

I'm impressed shell does this! and have my own function to add to the list of "Commands that Compose." dryrun[1]: when prefixed on a shell command, it echos the command if DRYRUN is set otherwise runs it normally. I pipe that to drytee[2] if the command's modifying files. I like it as a more deliberate (and safer) alternative to 'set -x' for debugging shell scripts.

   for f in in/*; do
     args=($(complicated_code $f))
     dryrun long_procces $f "${args[@]}" | drytee out/${f//*\//}
   end
[0]<http://www.catb.org/%7Eesr/writings/taoup/html/ch06s06.html>

[1] https://github.com/lncd/lncdtools/blob/master/dryrun

[2] https://github.com/lncd/lncdtools/blob/master/drytee

By @aljarry - 5 months

  retry() {
    local n=$1
    shift
    for i in $(seq $n); do
      "$@"
    done
  }
This is not a retry function, it's a "run a function 5 times" function. Retry would check the outcome of the operation, and only for failed cases would run it additional times. It is definitely possible in bash, it's just a few more lines.