Required reading: rc, es
Simplest shell: just run cmd arg arg... - fork, exec in child, wait in parent.
More functionality: file redirection cmd >file - open file as fd 1 in child before exec
Still more functionality: pipes cmd | cmd - create a pipe, run first cmd with pipe on fd 1, run second cmd with other end of pipe on fd 0.
More Bourne arcana: $*, $@, environment variables, macro substitution, if, while, for, ||, &&, "foo $x", 'foo $x', `foo`.
No reparsing of input. (except explicit eval)
variables as lists
explicit concatenation
multiple input pipes <{cmd} - pass /dev/fd/4 as file name.
syntax more like C, less like Algol
goal is to override functionality cleanly
rewrite input like cmd | cmd2 as %pipe {cmd} {cmd2}.
users can redefine %pipe, etc.
need lexical scoping and let to refer to old values of %pipe
need garbage collection to figure out when functions aren't needed anymore
design principle: provide minimal pieces of functionality along with good default implementations of higher-level functionality, but let users customize these implementations: emacs, exokernel.
more abstract - higher level
concise syntax
simpler
easier for file manipulation, process manipulation
batch programming
portability
interactive development environment
connecting programs together
string and character manipulation (sometimes)
speed
large programs
data structures
some functionality is hidden (e.g., networks, but can use nc instead; guis harder).
scripting languages fix data structures, functionality, can now write guis
lost default behaviors that are convenient - manipulation of files, programs, pipes
acme juke box player - turn events into command stream
double-indirection: a=5 b=a echo $$b => 5.