From: Sacha
Subject: read preserving case for a while
Date: 
Message-ID: <C06Th.114505$15.809081@phobos.telenet-ops.be>
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

From: Zach Beane
Subject: Re: read preserving case for a while
Date: 
Message-ID: <m3k5wjc7xm.fsf@unnamed.xach.com>
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
From: Sacha
Subject: Re: read preserving case for a while
Date: 
Message-ID: <aN6Th.114572$wG4.960540@phobos.telenet-ops.be>
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
From: Alan Crowe
Subject: Re: read preserving case for a while
Date: 
Message-ID: <86slb4gpot.fsf@cawtech.freeserve.co.uk>
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.)
From: Harald Hanche-Olsen
Subject: Re: read preserving case for a while
Date: 
Message-ID: <pcobqhkx0og.fsf@shuttle.math.ntnu.no>
+ 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
From: Rob Warnock
Subject: Re: read preserving case for a while
Date: 
Message-ID: <cumdnb863pdRv7rbnZ2dnUVZ_umlnZ2d@speakeasy.net>
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