Erik Naggum <clerik@naggum.no> wrote:
+---------------
| I take this to mean that you think the lexical analysis of Scheme and
| Common Lisp are similar or the same. this is not so. Common Lisp has a
| programmable reader that is used to read Lisp forms, while Scheme uses a
| very static syntax that is even outside of Scheme itself. (i.e., Common
| Lisp uses READ and uses the value of *READTABLE* even for code, while
| Scheme cannot use READ because the syntax is specified as sequences of
| characters, not as forms.)
+---------------
Erik, I assume you're wearing some sort of "standards purist" hat while
saying this...? ;-} Yes, of course, in principle you are absolutely
correct, but in practice I don't know of a single Scheme implementation
that does *NOT* use the same lexer for the user-visible READ procedure and
the reader buried in the LOAD procedure and the top-level REPL. In fact,
now that EVAL is in R5RS, one could even make Scheme's LOAD an optional
procedure, which could be coded by the user as:
(define (load fname)
(with-input-from-file fname
(lambda ()
(do ((exp (read) (read)))
((eof-object? exp)) ; note: returns unspec. value
(eval exp (interaction-environment))))))
And, except for the lack of error-handling, this:
(let loop ()
(display "my-repl> ")
(write (eval (read) (interaction-environment)))
(newline)
(loop))
is a perfectly functional REPL in every Scheme I've ever used. [O.k.,
so you have to leave off the 2nd arg to "eval" in the older ones...]
In fact, I can't see any way to *avoid* this, since R5RS explictly says
that READ "...is a parser for the nonterminal <datum>" [6.6.2], and
also, "Note that any string that parses as an <expression> also parses
as a <datum>." [7.1.2] So it should be perfectly correct to use READ
for Scheme expressions (well-formed ones, that is).
On the other hand... There is no defined way in Scheme to extend or modify
the syntax accepted by READ. With only one or two ad-hoc exceptions (dare I
say "hacks"?), I haven't seen anything in the Scheme world that comes close
to the Common Lisp notion of *READTABLE*, and certainly nothing that works
the same way in more than one implementation. And that's quite unfortunate,
given the wide differences in lexical "extensions" supported by various
Schemes. Some allow |CaseSensitiveSymbols With Spaces InVerticalBars| and
some don't. Some allow #|multi-line comments|# and some don't. A very few
support "#."; most don't. Were there a widely-accepted readtable-equivalent,
one could gloss over these differences. But as it is, if one is trying to
write Scheme code which will be even barely portable, one must simply avoid
*everything* that's not explcitly mentioned in R5RS [or even R4RS]. (*sigh*)
Hmmmm... But on the third hand [as Niven & Pournelle say], in R5RS "READ"
is listed as a "library" procedure, which means that while conforming
implementations must provide one [it's not an "optional" library procedure]
it need not be primitive -- it can be implemented in terms of other, more
primitive features. Just start with "READ-CHAR", and parse it yourself.
(I've done that before, actually, as an exercise.) There are enough required
type-conversion routines [I'm thinking specifically of "string->symbol"
and "char->integer"] to allow building any Scheme object up out of pieces.
Maybe *that's* supposed to be "the Scheme way" to get reader extensibility...?
-Rob
-----
Rob Warnock, 8L-855 rpw3@sgi.com
Applied Networking http://reality.sgi.com/rpw3/
Silicon Graphics, Inc. Phone: 650-933-1673
2011 N. Shoreline Blvd. FAX: 650-964-0811
Mountain View, CA 94043 PP-ASEL-IA