Hello all,
I'd like to have part of a source file to be read preserving case.
something like this :
;; normal lisp code
(defparameter *the-string*
(with-read-case-preserved
(def-computed-string
;;some lispy but non-lisp code
;;where symbols need to be case-sensitive
)))
;; back to normal lisp code
I'm at loss as to how i should write the with-read-case-preserved macro,
as it seems to me that it will be computed at macro-expention time,
which is after read-time.
Any ideas ?
Thanks in advance,
Sacha
Sacha <····@address.spam> writes:
> Hello all,
>
> I'd like to have part of a source file to be read preserving case.
>
> something like this :
>
> ;; normal lisp code
>
> (defparameter *the-string*
> (with-read-case-preserved
> (def-computed-string
> ;;some lispy but non-lisp code
> ;;where symbols need to be case-sensitive
> )))
>
> ;; back to normal lisp code
>
>
> I'm at loss as to how i should write the with-read-case-preserved
> macro, as it seems to me that it will be computed at macro-expention
> time, which is after read-time.
I don't think you can do it as a regular macro, but I think you can do
it with a read macro.
(defparameter *the-string*
#~(def-computed-string ...))
Zach
Zach Beane wrote:
> Sacha <····@address.spam> writes:
>> ;; normal lisp code
>>
>> (defparameter *the-string*
>> (with-read-case-preserved
>> (def-computed-string
>> ;;some lispy but non-lisp code
>> ;;where symbols need to be case-sensitive
>> )))
>>
>> ;; back to normal lisp code
>>
>
> I don't think you can do it as a regular macro, but I think you can do
> it with a read macro.
>
> (defparameter *the-string*
> #~(def-computed-string ...))
>
> Zach
Thanks a lot !
Here is the result :
(defun tilde-reader (stream char)
(declare (ignore char))
(let ((*readtable* (copy-readtable)))
(setf (readtable-case *readtable*) :preserve)
(read stream t nil t)))
(set-macro-character #\~ #'tilde-reader)
TEST 233 > ~'(Ablah catr SOUsou)
(|Ablah| |catr| |SOUsou|)
That's perfect =)
Sacha
From: Richard M Kreuter
Subject: Re: read preserving case for a while
Date:
Message-ID: <87wt0isvxk.fsf@progn.net>
Sacha <····@address.spam> writes:
> I'd like to have part of a source file to be read preserving case.
>
> something like this :
>
> ;; normal lisp code
>
> (defparameter *the-string*
> (with-read-case-preserved
> (def-computed-string
> ;;some lispy but non-lisp code
> ;;where symbols need to be case-sensitive
> )))
>
> ;; back to normal lisp code
>
> I'm at loss as to how i should write the with-read-case-preserved
> macro, as it seems to me that it will be computed at macro-expention
> time, which is after read-time.
Conventionally, Lisp's read-eval-print loop parses the whole form
before evaluating it, and so the body of with-read-case-preserved will
have been read before with-read-case-preserved gets executed. You
might want to have a look at Kent Pitman's "Ambitious Evaluation: A
New Reading of an Old Issue" for a more thorough treatment of this
point:
http://www.nhplace.com/kent/PS/Ambitious.html
> Any ideas ?
Zach Beane mentioned that you could use a read macro; another approach
would be to define a pair of macros that expand to EVAL-WHENs that
frob and unfrob the readtable. Then you'd put your code between the
two expressions. CLSQL's has a reader syntax that's enabled/disabled
this way; maybe you could look at that for inspiration.
--
RmK
Sacha <····@address.spam> writes:
> I'd like to have part of a source file to be read preserving case.
>
> Any ideas ?
>
CL-USER> (read)
(aBc #.(progn (setf (readtable-case *readtable*) :preserve)(values))
DeF
gHi
#.(PROGN (SETF (READTABLE-CASE *READTABLE*) :UPCASE)(VALUES))
Jkl)
(ABC |DeF| |gHi| JKL)
Alan Crowe
Edinburgh
Scotland
From: Kent M Pitman
Subject: Re: read preserving case for a while
Date:
Message-ID: <u3b2xw9ka.fsf@nhplace.com>
Alan Crowe <····@cawtech.freeserve.co.uk> writes:
> Sacha <····@address.spam> writes:
>
> > I'd like to have part of a source file to be read preserving case.
> >
> > Any ideas ?
> >
>
> CL-USER> (read)
> (aBc #.(progn (setf (readtable-case *readtable*) :preserve)(values))
> DeF
> gHi
> #.(PROGN (SETF (READTABLE-CASE *READTABLE*) :UPCASE)(VALUES))
> Jkl)
>
> (ABC |DeF| |gHi| JKL)
>
> Alan Crowe
> Edinburgh
> Scotland
There's worked code elsewhere on this thread to show how to bind it
through a readmacro. That's one way to go.
The other way is to globally create a readtable (call it
*MY-CASE-INSENSITIVE-READTABLE*) and arrange it as you like. Then
make a copy and set readtable case the other way (call it
*MY-CASE-SENSITIVE-READTABLE*). Then define a macro IN-SYNTAX as
(DEFMACRO IN-SYNTAX (READTABLE)
`(EVAL-WHEN (:EXECUTE :COMPILE-TOPLEVEL :LOAD-TOPLEVEL)
(SETQ *READTABLE* ,READTABLE)))
Then at the toplevel of your file at various points you can do:
(IN-SYNTAX *MY-CASE-SENSITIVE-READTABLE*)
... forms that are case-sensitive ...
(IN-SYNTAX *MY-CASE-INSENSITIVE-READTABLE*)
Note that the second of the two IN-SYNTAX forms _must_ be in uppercase,
while the others only optionally have to be. I'd do them all in uppercase
just to not have to remember it. But once you're case-sensitive, the
macro and the variable that is its arg will only be visible in the right
case.
I had originally proposed not only making *READTABLE* be bound by LOAD and
COMPILE-FILE, but also adding this macro named IN-SYNTAX. Larry Masinter
rewrote this to just offer the minimal proposal and removed the full-blown
suggestion of an IN-SYNTAX macro in version 3 of that proposal.
http://www.lispworks.com/documentation/HyperSpec/Issues/iss196_w.htm
I guess the notion was that it was better to leave this as an exercise to
the user. (To this day, I disagree that this was a good decision. But
at least we kept enough that users _could_ write their own. I use such a
macro all the time myself, not to set case sensitivity, but to select other
readmacros on a per-file basis.)
+ Kent M Pitman <······@nhplace.com>:
| Then at the toplevel of your file at various points you can do:
|
| (IN-SYNTAX *MY-CASE-SENSITIVE-READTABLE*)
| ... forms that are case-sensitive ...
| (IN-SYNTAX *MY-CASE-INSENSITIVE-READTABLE*)
|
| Note that the second of the two IN-SYNTAX forms _must_ be in
| uppercase, while the others only optionally have to be. I'd do them
| all in uppercase just to not have to remember it.
You're assuming, of course, that the user is not perverse enough to
use :invert, in which case the first form _must_ be in lowercase.
(I am that perverse myself. I find it both astonishing and pleasing
that this almost never causes any trouble in loading other people's
code.)
--
* Harald Hanche-Olsen <URL:http://www.math.ntnu.no/~hanche/>
- It is undesirable to believe a proposition
when there is no ground whatsoever for supposing it is true.
-- Bertrand Russell
Harald Hanche-Olsen <······@math.ntnu.no> wrote:
+---------------
| + Kent M Pitman <······@nhplace.com>:
| | Note that the second of the two IN-SYNTAX forms _must_ be in
| | uppercase, while the others only optionally have to be. I'd do them
| | all in uppercase just to not have to remember it.
|
| You're assuming, of course, that the user is not perverse enough to
| use :invert, in which case the first form _must_ be in lowercase.
|
| (I am that perverse myself. I find it both astonishing and pleasing
| that this almost never causes any trouble in loading other people's code.)
+---------------
Ditto. When "case-preserving" input is required, I consider :INVERT
to result in a *much* more "natural" human interface than the alternatives.
[I put "case-preserving" in quotes because what is usually *actually*
needed is not case-preserving-READ at all, but READ/PRINT-case-invariance
(as when reading/writing C variables as symbols), and for that purpose
:INVERT is really a better choice, since you can turn it on once and
leave it on...]
-Rob
-----
Rob Warnock <····@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607