whampa <gte793z@prism.gatech.edu> wrote:
+---------------
| Also, if it interests you, a lot of development is being done for Scheme
| Shell( http://www.scsh.net/ ). It's an open source Unix shell that can do
| many fun and wonderful things with scheme. I'd recommend reading this guy's
| page http://www.cc.gatech.edu/~shivers/ and contacting him if you have any
| sort of interesting.
+---------------
That brings up a question about the CL reader I've been wondering about
for some time, inasmuch as I've occasionally mused about doing something
like the Scheme Shell in CL...
Scsh makes heavy use of [non-hygenic, defmacro-like] macros for syntactic
sugar, especially for what it calls "process forms" (PFs) and "extended
process forms" (EPFs) in which subforms are "implicitly backquoted". That
is, you can use comma and comma-at *without* typing an initial backquote.
A couple of small examples[1] using the RUN macro, one of the main EPFs,
will show you what I mean:
;; If the resource file F exists, load it into X Windows.
(when (probe-file f)
(run (xrdb -merge ,f)))
;; Compile FILE with FLAGS.
(run (cc ,file ,@flags))
;; Delete every file in DIR containing the string "/bin/perl":
(dolist (file (directory dir))
(if (zerop (run (grep -s /bin/perl ,file)))
(delete-file file)))
The problem is that I can see no way in ANSI Common Lisp of defining
the RUN macro such that it would permit this syntax to be acceptable
to the CL reader.[2] Am I missing something obvious? Or is this in fact
a fundamental limitation, such that the closest one could come to the
above would be this?
(when (probe-file f)
(run `(xrdb -merge ,f)))
(run `(cc ,file ,@flags))
O.k., let me restate that -- I should have said: The only way I see to
use exactly Scsh-like syntax would be to define one's own reader macros
for backquote and comma, effectively replacing the built-in ones with
one's own. [Yes, you could, I suppose, do something like temporarily
restore the original definitions when you see a backquote until that
subexpression is read and then pop back to your own, but it would
probably be easier overall to do the whole thing yourself and not try
to mix the styles].
So to repeat: Am I missing something simple/obvious? Or is that the
best one can do?
-Rob
[1] These are mildly edited into CL syntax from the Scsh examples here:
<URL:http://www.scsh.net/docu/scsh-paper/scsh-paper-Z-H-5.html>
[2] In Scheme 48 [the engine underneath Scsh] it's fairly simple, since
backquote, comma, and comma-at are defined as being simple QUOTE-like
abbreviations for a longer S-expression syntax, defined completely in
isolation of each other. That is, in Scheme:
'form ==> (quote form)
`form ==> (quasiquote form)
,form ==> (unquote form)
,@form ==> (unquote-splicing form)
Given these isolated transformations[3], QUASIQUOTE can simply be a
macro that tree-walks its argument, rewriting any S-expr sub-forms
whose CAR is one of QUASIQUOTE/UNQUOTE/UNQUOTE-SPLICING.
In CL, on the other hand, the comma & comma-at are not defined in
isolation, but only in the context of an open backquote; also, unlike
Scheme, no standard list representation of a backquoted expression
is mandated, only that [per CLHS "2.4.6 Backquote"]:
An implementation is free to interpret a backquoted form F1 as
any form F2 that, when evaluated, will produce a result that is
the same under EQUAL as the result implied by the above definition,
provided that the side-effect behavior of the substitute form F2
is also consistent with the description given above.
[3] Note that like CL, the R5RS standard officially only defines UNQUOTE
and UNQUOTE-SPLICING when they appear within a QUASIQUOTE template,
however Scheme 48, MzScheme, and several other implementations are
more lenient in their behavior, e.g., in MzScheme:
> '(run (cc ,file ,@flags))
(run (cc (unquote file) (unquote-splicing flags)))
>
-----
Rob Warnock, PP-ASEL-IA <rpw3@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607