From: JP Massar
Subject: Problems with the semantics of *read-suppress*
Date: 
Message-ID: <3e0775ee.49512429@netnews.attbi.com>
I believe the Hyperspec says that

(let ((*read-suppress* t)) (read-from-string "#\GARBAGE"))

should return NIL.

See the Example: part of


http://www.lispworks.com/reference/HyperSpec/Body/v_rd_sup.htm#STread-suppressST

But 3 out of 3 implementations (Allegro, LispWorks and Corman)
all choke.

---------

LISPWORKS 4.1

CL-USER 4 : 1 > (let ((*read-suppress* t)) 
                    (read-from-string "#\GARBAGE"))

Error: Subcharacter #\G not defined for dispatch char #\#.

-----------

Allego 6.1

CG-USER(3): (let ((*read-suppress* t)) (read-from-string "#\GARBAGE"))
Error: No dispatch function defined for #\G.

------------

Corman 2.0

(let ((*read-suppress* t)) (read-from-string "#\GARBAGE"))
;;; An error occurred in function READ-EXPRESSION:
;;; Error: Invalid input form


In fact I have encountered all sorts of problems in all three
implementations trying to read past such things as

#\)

#\*

using *READ-SUPPRESS*


I find it hard to believe that 3 out 3 implementations are getting
this wrong, so am I not understanding something or does some
other part of the Hyperspec shed other light on this?

Thanks.

From: Edi Weitz
Subject: Re: Problems with the semantics of *read-suppress*
Date: 
Message-ID: <87adiwfk44.fsf@bird.agharta.de>
······@alum.mit.edu (JP Massar) writes:

> I believe the Hyperspec says that
> 
> (let ((*read-suppress* t)) (read-from-string "#\GARBAGE"))
> 
> should return NIL.
> 
> See the Example: part of
> 
> 
> http://www.lispworks.com/reference/HyperSpec/Body/v_rd_sup.htm#STread-suppressST
> 
> But 3 out of 3 implementations (Allegro, LispWorks and Corman)
> all choke.
> 
> ---------
> 
> LISPWORKS 4.1
> 
> CL-USER 4 : 1 > (let ((*read-suppress* t)) 
>                     (read-from-string "#\GARBAGE"))
> 
> Error: Subcharacter #\G not defined for dispatch char #\#.
> 
> -----------
> 
> Allego 6.1
> 
> CG-USER(3): (let ((*read-suppress* t)) (read-from-string "#\GARBAGE"))
> Error: No dispatch function defined for #\G.
> 
> ------------
> 
> Corman 2.0
> 
> (let ((*read-suppress* t)) (read-from-string "#\GARBAGE"))
> ;;; An error occurred in function READ-EXPRESSION:
> ;;; Error: Invalid input form
> 
> 
> In fact I have encountered all sorts of problems in all three
> implementations trying to read past such things as
> 
> #\)
> 
> #\*
> 
> using *READ-SUPPRESS*

CMUCL 18e-pre:

···@bird:/tmp > cmucl
; Loading #p"/home/edi/.cmucl-init".
CMU Common Lisp 18e-pre, built 2002-12-19 on melbourne, running on bird.agharta.de
Send questions to ··········@cons.org. and bug reports to ·········@cons.org.
Loaded subsystems:
    Python 1.0, target Intel x86
    CLOS based on PCL version:  September 16 92 PCL (f)
* (let ((*read-suppress* t)) (read-from-string "#\GARBAGE"))

NIL
8


Edi.
From: JP Massar
Subject: Re: Problems with the semantics of *read-suppress*
Date: 
Message-ID: <3e07adb7.63796529@netnews.attbi.com>
On 23 Dec 2002 23:25:47 +0100, Edi Weitz <···@agharta.de> wrote:

>······@alum.mit.edu (JP Massar) writes:
>
>> I believe the Hyperspec says that
>> 
>> (let ((*read-suppress* t)) (read-from-string "#\GARBAGE"))
>> 
>> should return NIL.
>> 
 
>
>···@bird:/tmp > cmucl
>; Loading #p"/home/edi/.cmucl-init".
>CMU Common Lisp 18e-pre, built 2002-12-19 on melbourne, running on bird.agharta.de
>Send questions to ··········@cons.org. and bug reports to ·········@cons.org.
>Loaded subsystems:
>    Python 1.0, target Intel x86
>    CLOS based on PCL version:  September 16 92 PCL (f)
>* (let ((*read-suppress* t)) (read-from-string "#\GARBAGE"))
>
>NIL
>8
>
 

Well, it turns out that the Hyperspec example is just plain WRONG.

The Hyperspec example has "#\Garbage" when presumably the intention
was to have "#\\Garbage", showing that some unidentified character
name is okay when *read-suppress* is T.

Using "#\Garbage" should generate an error because there is no 
dispatch macro for the character 'G'.

I don't know why CMUCL does not generate an error.
From: Christophe Rhodes
Subject: Re: Problems with the semantics of *read-suppress*
Date: 
Message-ID: <sqk7hx234e.fsf@lambda.jcn.srcf.net>
······@alum.mit.edu (JP Massar) writes:

> On 23 Dec 2002 23:25:47 +0100, Edi Weitz <···@agharta.de> wrote:
> 
> >* (let ((*read-suppress* t)) (read-from-string "#\GARBAGE"))
> >
> >NIL
> >8
> >
>  
> 
> Well, it turns out that the Hyperspec example is just plain WRONG.
> 
> The Hyperspec example has "#\Garbage" when presumably the intention
> was to have "#\\Garbage", showing that some unidentified character
> name is okay when *read-suppress* is T.

I think you're right about the intent of the example.  However...
 
> Using "#\Garbage" should generate an error because there is no 
> dispatch macro for the character 'G'.

... is this stated anywhere?  I agree that, for instance,
(read-from-string "#\<") should signal an error, because the dispatch
macro function for #< is defined to signal an error; but when there is
no dispatch function?

[ handwavy justification for why one might not want to throw an error:
  *read-suppress* is used in the implementation of #+/#-, and it would
  be reasonable, if not great style, to want to do something along the
  following lines:
  (defun foo (z)
    #+fooimpl #g(frob)
    #-fooimpl ... some longer bit of code ...) ]

To put it another way, I think it's legal for an implementation to
have, as its internal handling function for undefined dispatch macro
characters, something along the lines of
  (defun dispatch-char-error (stream char infix)
    (if *read-suppress*
        (values)
        (error 'reader-error ...)))
but I'm acutely aware that I may have missed something that forbids
this.

Cheers,

Christophe
-- 
http://www-jcsu.jesus.cam.ac.uk/~csr21/       +44 1223 510 299/+44 7729 383 757
(set-pprint-dispatch 'number (lambda (s o) (declare (special b)) (format s b)))
(defvar b "~&Just another Lisp hacker~%")    (pprint #36rJesusCollegeCambridge)
From: JP Massar
Subject: Re: Problems with the semantics of *read-suppress*
Date: 
Message-ID: <3e0a6f7a.20125222@netnews.attbi.com>
On 25 Dec 2002 21:35:45 +0000, Christophe Rhodes <·····@cam.ac.uk>
wrote:

 
> 
>> Using "#\Garbage" should generate an error because there is no 
>> dispatch macro for the character 'G'.
>
>... is this stated anywhere? 

From the Hyperspec:

"Dispatching macro characters (including sharpsign):

   Dispatching macro characters continue to parse an infix numerical
argument, and invoke the dispatch function."


> I agree that, for instance,
>(read-from-string "#\<") should signal an error, because the dispatch
>macro function for #< is defined to signal an error; but when there is
>no dispatch function?
>
 
>
>To put it another way, I think it's legal for an implementation to
>have, as its internal handling function for undefined dispatch macro
>characters, something along the lines of
>  (defun dispatch-char-error (stream char infix)
>    (if *read-suppress*
>        (values)
>        (error 'reader-error ...)))
>but I'm acutely aware that I may have missed something that forbids
>this.
>
 
If the implementation has effectively defined the dispatch function
for all undefined dispatch chars as you suggest, then, assuming that
there is no Hyperspec requirement that these dispatch characters
be left undefined (say, for users to use), then I agree that this 
seems like a valid implementation.

If there is a requirement to leave some characters undefined then I
think an error must be signalled when one of those is encountered
and the user has not defined the dispatch for that character.
From: Pekka P. Pirinen
Subject: Re: Problems with the semantics of *read-suppress*
Date: 
Message-ID: <u65stcfaf.fsf@globalgraphics.com>
······@alum.mit.edu (JP Massar) writes:
> On 25 Dec 2002 21:35:45 +0000, Christophe Rhodes <·····@cam.ac.uk>
> wrote:
> >To put it another way, I think it's legal for an implementation to
> >have, as its internal handling function for undefined dispatch macro
> >characters, something along the lines of
> >  (defun dispatch-char-error (stream char infix)
> >    (if *read-suppress*
> >        (values)
> >        (error 'reader-error ...)))
> >but I'm acutely aware that I may have missed something that forbids
> >this.

The reason this is not in the standard is that it's not useful,
because the handler can't know how much of the input stream to ignore
when suppressing, as each dispatch macro has its own idiosyncratic
syntax.  Consider an example similar to yours:
  (#+foo #Garbage)
where #Garbage is a single expression when #G is defined.  If the
reader just suppressed the error on #G, it would then read the symbol
ARBAGE, which is not what we needed.

> assuming that there is no Hyperspec requirement that these dispatch
> characters be left undefined (say, for users to use)

Well, users can redefine any dispatch characters, even if they already
have a definition.  But there is exactly such a requirement in the
standard, ANS 2.4.8 "The combinations marked by an asterisk (*) are
explicitly reserved to the user. No conforming implementation defines
them."
-- 
Pekka P. Pirinen
Pick your enemies carefully.  They're harder to get rid of than friends.