5 The Tao of Scheme and Unix
Most attempts at embedding shells in functional programming languages [fsh, Ellis] try to hide the difference between running a program and calling a procedure. That is, if the user tries
(lpr "notes.txt")the shell will first treat lpr as a procedure to be called. If lpr isn't found in the variable environment, the shell will then do a path search of the file system for a program. This sort of transparency is in analogy to the function-binding mechanisms of traditional shells, such as ksh.
This is a fundamental error that has hindered these previous designs. Scsh, in contrast, is explicit about the distinction between procedures and programs. In scsh, the programmer must know which are which -- the mechanisms for invocation are different for the two cases (procedure call versus the (run . epf) special form), and the namespaces are different (the program's lexical environment versus $PATH search in the file system).
Linguistically separating these two mechanisms was an important design decision in the language. It was done because the two computational models are fundamentally different; any attempt to gloss over the distinctions would have made the semantics ugly and inconsistent.
| ||||||||||
Figure 4: The Tao of Scheme and Unix | ||||||||||
There are two computational worlds here (figure 4), where the basic computational agents are procedures or processes. These agents are composed differently. In the world of applicative-order procedures, agents execute serially, and are composed with function composition: (g (f x)). In the world of processes, agents execute concurrently and are composed with pipes, in a data-flow network: f | g. A language with both of these computational structures, such as scsh, must provide a way to interface them. {Note Normal order} In scsh, we have ``adapters'' for crossing between these paradigms:
The run/string form and its cousins (section 3.5) map process output to procedure input; the << i/o redirection maps procedure output to process input. For example:
Scheme Unix Scheme (g (f x)) (<< ,x) Unix run/string,... f | g
By separating the two worlds, and then providing ways for them to cross-connect, scsh can cleanly accommodate the two paradigms within one notational framework.
(run/string (nroff -ms)
(<< ,(texinfo->nroff doc-string)))