Subject: Re: ELisp converts to Lisp
From: rpw3@rpw3.org (Rob Warnock)
Date: Thu, 06 Jan 2005 05:13:59 -0600
Newsgroups: comp.lang.lisp
Message-ID: <t_qdnUYDZbXqgEDcRVn-qQ@speakeasy.net>
Julian Stecklina  <der_julian@web.de> wrote:
+---------------
| "projectshave@yahoo.com" <projectshave@yahoo.com> writes:
| > I'd wager that the lack of a small Lisp environment for writing quick &
| > dirty utilities *might* be a reason. ...
| 
| scsh, the scheme shell, is a very nice thing to write utilities in.
| Would be a nice candidate to port to ECL or GCL, though.
+---------------

I agree, Scsh is nice, but... There's a problem with trying to
implement Scsh *exactly* in Common Lisp, namely, in Common Lisp
there is no standard list representation defined for the result
of a READ of the comma or comma-at syntax, nor does Common Lisp
permit comma or comma-at syntax which is not properly nested within
backquote syntax to be read in forms to be evaluated.

In Scheme, on the other hand, backquote, comma, and comma-at are
merely read macros much like quote and sharp-quote in Common Lisp.
That is, each of backquote, comma, and comma-at are *defined*
to produce a specific internal list representation for each,
which can reliably be manipulated by a user-defined tree walker.

To say it another way, in both CL and Scheme [using "==>" here to
mean "is READ as"]:

	'a ==> (quote a)

and in CL [though not Scheme]:

	#'a ==> (function a)

But in Scheme -- though *NOT* in CL! -- the following all have
similarly-definite READ representations defined:

	`a ==> (quasiquote a)
	,a ==> (unquote a)
	,@a ==> (unquote-splicing a)

That is, the QUASIQUOTE, UNQUOTE, and UNQUOTE-SPLICING symbols are
all special operators when a quasiquoted form is evaluated, but more
importantly, they have defined READ representations as non-evaluated
*data* as well. This means that Scheme macros can contain argument
forms which contains comma or comma-at syntax which is *NOT* properly
nested within backquotes, and also that the macros [and any tree
walkers they contain] can depend on the structure of the READ results.

Why does this matter? Because much of the convenience of Scsh comes
from the fact that a large number of the most-commonly-used macros
in Scsh "implicitly backquote" their arguments. For example, this
is legal Scsh:

	(let ((foo "filename"))
	  (run (ls -l ,foo)))	; Note no backquote before the comma!

That's simply not possible with most CL readers [and certainly not
portable CL in any case].

Yes, for each short macro form there is a longer functional form that
could be made to work in CL, but it's much less succinct. The above
example could be re-written as follows:

	(let ((foo "filename"))
	  (wait (fork (lambda () (exec-path `(ls -l ,foo))))))

Still, it might be possible to come up with CL versions of the "run",
"fork", "pipe", etc. macros that *don't* try to implicitly backquote
their arguments, and which must be given explicitly backquoted args.
That is, the original example could work in CL if it looked liked this:

	(let ((foo "filename"))
	  (cl-run `(ls -l ,foo)))

But this is still not adequate for portability, since different
CL implementation represent the results of reading `(ls -l ,foo)
differently. For example, [if you work *really* hard to peek under
the covers] you will find CLISP gives the following [very much
like the Scheme standard, actually]:

	(SYSTEM::BACKQUOTE (LS -L (SYSTEM::UNQUOTE FOO)))

whereas CMUCL gives this:

	(LISP::BACKQ-LIST (QUOTE LS) (QUOTE -L) FOO)

Both will give equivalent results when *evaluated* by their
corresponding evaluators, but the unevaluated forms are sufficiently
different to make it "interesting" to implement the full set of
Scsh macros [which need to walk the unevaluated backquoted forms
rewriting them into their equivalent functional forms]. And that's
just two versions of CL...


-Rob

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607