scsh-users
[Top] [All Lists]

Re: Perl, English, syntax for Scheme and shells (was Re: scsh in scm ...

To: scsh@martigny.ai.mit.edu
Subject: Re: Perl, English, syntax for Scheme and shells (was Re: scsh in scm ...)
From: sethml@ugcs.caltech.edu (Seth M. LaForge)
Date: 4 Jan 1996 11:17:23 GMT
Organization: California Institute of Technology, Pasadena, CA USA
In article <4cc999$424@jive.cs.utexas.edu>, Paul Wilson wrote:
>I personally can't stand Tcl, which
>is why I'm interested in coming up with a "command syntax" for Scheme shell
>programming.
>
>I firmly believe that Scheme is a better basis for such things, if
>we come up with some handy syntax that can easily be explained.
>
>Comments?

I've recently been getting into es, which is a shell based on rc, the
Plan 9 shell.  I think es fulfills many of the goals you've outlined
above quite nicely.  It has a fairly standard shell syntax, but that
syntax is just sugar which expands into more consistent primitives:

   ; echo { ps -fe | grep syslogd }
   {%pipe {ps -fe} 1 0 {grep syslogd}}

The curly brackets enclose executable code.  It's stored internally as
syntax trees, but can be flattened for display and output to the
environment.  It supports lexical scoping:

   ; foo = toplevel
   ; let ( foo = lexical ) {    # Introduce a lexical variable
        echo $foo
     }
   lexical
   ; fn print-foo { echo $foo } # Defines a function
   ; let ( foo = lexical ) {
        echo $foo
        print-foo
     }
   lexical
   toplevel

There are also closures!

   ; let ( foo = lexical) {
        fn lexical-print-foo { echo $foo }
     }
   ; lexical-print-foo
   lexical
   ; echo $fn-lexical-print-foo         # Functions are stored in variables
   %closure(foo=lexical)@ * {echo $foo}

There is a lambda form:

   ; @ items { for ( x = $items ) { echo argument: $x } } ( a b c )
   argument: a
   argument: b
   argument: c

The form '( a b c )' is a list.  The for loop iterates over a list.
es supports lists fairly well, although unfortunately lists cannot be
nested.  Lists are NOT just space seperated strings as in TCL!  (Thank
god!)

Putting all of the above together, here's an example which I doubt
could be achieved as elegantly in any other shell:

   ; fn make-generator {
       let ( result = 0 ) {
         return @ {
           result = `{ expr $result + 1 }
           return $result
         }
       }
     }
   ; generator1 = <={ make-generator }          # <={} expands to the
   ; generator2 = <={ make-generator }          # return value
   ; echo <={ $generator1 }
   1
   ; echo <={ $generator1 }
   2
   ; echo <={ $generator1 }
   3
   ; echo <={ $generator1 }
   1
   ; echo <={ $generator2 }
   2

Overall, I really like es.  It has some problems.  The shell could
badly use a little more powerful structures - nested lists and
associative arrays would really help.  Some of the syntax is rather
clumsy, but I think this is somewhat inevitable.  I think es does a
fine job of integrating a relatively powerful language into an
unfriendly environment - it handles many things well, such as
exporting functions to subshells through the environment through the
above-mentioned flattening mechanism.

Unfortunately, I find es a little too weak for interactive use.  It's
fairly usable with GNU readline compiled in (thank god for vi key
bindings!), but lack of job control is a pretty serious limitation.
I think job control could probably be written in the shell with a
very small amount of built in support.

I really love it for scripting though.  The only problem areas I've
come across there is slowness because of lack of a few built-in
operators.  Built-in test and expr would be nice.

In any case, I encourage people to check out es.  It's pretty cool.
It's available from ftp://ftp.sys.utoronto.ca/pub/es.

Seth


<Prev in Thread] Current Thread [Next in Thread>