NAME
     lab 28 - side effects

DESCRIPTION
     I was planning on just implementing side effects,
     but it turned out to be a little more complicated
     than I thought, and then I got sidetracked into
     changing the evaluator to handle more of the shell
     semantics.

     The file lisp7.b implements setq but it is limited
     in that in cannot change the type of the value
     referenced by the symbol.

          % eval {setq a `{b c d}}
          (b c d)
          % eval {setq a `b}
          error at type mismatch
          (b c d)

     Fixing this requires me re-implementing the sepxrs
     library to remove pick from the ADT. I'll follow
     up on this later.

  Mixing shell and lisp syntax
     The final parser in the Sussman and Steele paper
     The Art of the Interpreter puts dynamic scoped
     variables back into the evaluator. It maintains
     two environments, one for lexical and one for
     dynamic binding.

     Instead of having a different dynamic environment
     using sexprs, I used the shell Context for the
     dynamic state. I also kept the shell syntax for
     dereferencing a dynamic variable. These and the
     rest of the features in this post are in lisp8.b.

          % FullForm {x := 1; echo $x; echo x}
          (Block Seq (LocalAssign x "1") (echo (Var x)) (echo x))
          % eval {x := 1; echo $x; echo x}
          ("1")
          x
          ""

     The lisp evaluator in lisp8.b has some significant
     changes over the previous ones. I've gone back to
     treating shell syntax more like normal shell.
     Semi-colon is transformed to Seq and dollar to Var
     . Seq is equivalent to progn in scheme. Var
     dereferences a variable in the dynamic
     environment. Block tags a braced block which
     essentially quotes the whole block until
     explicitly eval'd.

     The evaluation for values is changed. If the
     variable is unbound, then it evaluates to itself,
     like the third reference to x above. 

     It also looks up shell commands for procedure
     calls. So the echo command works. We also no treat
     normal parentheses as nested list delimiters, and
     use applicative order for their evaluation. This
     essentially does away with the ${} syntax and
     substitution builtins.

          % eval {x := 1 2 3 4; echo (car $x)}
          1
          ""

     The language is beginning to get interesting. It
     looks like we have a lisp interpreter built into
     the handling of lists. But in fact the whole
     expression is converted to lisp form and
     evalutated. This means we can symbollically
     manipulate the shell commands.

          % eval {car {echo this}}
          Block

     The tricky thing now is to handle more of the
     shell semantics including globbing, file
     redirection and pipes.

     One assumes we will get a rather strange language
     at the end of it. Though I hope it will look a lot
     like shell with the full power of a symbolic
     programming language behind it.

     When calling external commands, such as echo, we
     need to catch the case where the command doesn't
     exist. I want to return a form that doesn't
     evaluate to anything as itself.

          % eval {asdf a b}
          sh: asdf: './asdf' file does not exist
          (asdf a b)

     Currently, shell prints the diagnostic that the
     command does not exist. I will later remove that
     when I move the language from a builtin to the
     main shell evaluator. The principle is one
     borrowed from computer algebra systems: Symbols
     evaluate to themselves if there is no other
     transformation.

     I added support for globbing. Globbing is somewhat
     like macros, we are rewriting the tree before the
     evaluator sees it.

          % eval {echo l*}
          (lisp8.sbl lisp8.dis lisp8.b lisp7.sbl lisp7.dis lisp7.b)
          ""

     I altered the FullForm for redirections and pipes
     but stopped short of actually implementing it.
     Because of lot of the code to do that is in 
     /appl/cmd/sh/sh.y and I thought it'd be easier to
     move the evaluator code back into sh.y and build a
     new shell. I will replace the walk function in
     that file with eval.

     Redirs are like property lists that carry with a
     command. The apply function needs to know about
     Redir. They evaluate to themselves, but when shell
     actually executes a command it pulls out the
     redirs from the expression.

          % FullForm {echo > t < x}
          (Block echo (Redir W t) (Redir R x))

CONCLUSION
     I like inferno shell. It is powerful. It can be
     made more powerful by making it a symbolic
     language. I don't lose any of its current power,
     in particular its expressiveness for building
     pipelines and working with files. But I add
     something more. The ability for it to see itself
     and manipulate it's own tree of code and data.

     It is useful to compare this with es shell. They
     took a similar idea, putting a lisp evaluator into
     the shell, but didn't take it to the extreme of
     what lisp can do. It doesn't appear the language
     could symbolically manipulate itself. 

FUTURE
     I will replace the shell evaluator with the one I
     have risen so far and so create a prototype for
     new language. I can then implement the backquote,
     redirection and pipes.