[Openmcl-devel] multiple read-time conditionals, puzzlement

Arthur Cater arthur.cater at ucd.ie
Mon Mar 13 10:20:16 PDT 2023


Just guessing, maybe READ-CONDITIONAL is inlined.

It never previously occurred to me that read time conditionals could be nested. Didn’t memorise the CL spec quite thouroughy enough. When I saw it done I became curious as to how it would behave. I guess I’m not alone.

Arthur

> On 13 Mar 2023, at 16:14, Ron Garret <ron at flownet.com> wrote:
> 
> Yep, definitely a bug.  CCL's behavior is inconsistent:
> 
> Clozure Common Lisp Version 1.12 (v1.12) DarwinX8664
> ? (list #+ccl #-ccl #+ccl 1 2 3)
> (3)
> ? (list #-nil #+nil #-nil 1 2 3)
> (2 3)
> 
> It's a really weird bug too:
> 
> ? (get-dispatch-macro-character #\# #\+)
> #<Compiled-function CCL::READ-CONDITIONAL #x300000562BFF>
> ? (get-dispatch-macro-character #\# #\-)
> #<Compiled-function CCL::READ-CONDITIONAL #x300000562BFF>
> ? (trace CCL::READ-CONDITIONAL)
> NIL
> ? #+ccl 1
> 1
> ? (trace ccl::read-feature)
> NIL
> ? #+ccl 1
> 
> 0> Calling (CCL::READ-FEATURE #<CCL::RECORDING-CHARACTER-INPUT-STREAM #x3020004F2E6D>) 
> <0 CCL::READ-FEATURE returned #\+
> 1
> 
> If you look at the source, the only place READ-FEATURE is called is in READ-CONDITIONAL, and yet the former is running but the latter is not.  We can even double-check to see that this is not a problem with TRACE:
> 
> ? (in-package :ccl)
> #<Package "CCL">
> ? (defun read-conditional (stream subchar int)
>   (print "Entering READ-CONDITIONAL")
>   (cond ((eq subchar (read-feature stream))
>          (multiple-value-bind (form note) (read-internal stream t nil t)
>            (values form (and note (list note)))))
>         (t (let* ((*read-suppress* t))
>              (read stream t nil t)
>              (values)))))
> ;Compiler warnings :
> ;   In READ-CONDITIONAL: Unused lexical variable INT
> READ-CONDITIONAL
> ? #+ccl 1
> 
> 0> Calling (READ-FEATURE #<RECORDING-CHARACTER-INPUT-STREAM #x3020004E03BD>) 
> <0 READ-FEATURE returned #\+
> 1
> 
> This is apparently a common bug.  ECL gets it wrong too:
> 
> ECL (Embeddable Common-Lisp) 21.2.1 (git:UNKNOWN)
> > (list #+ecl #-ecl #+ecl 1 2 3)
> (3)
> > (list #-nil #+nil #-nil 1 2 3)
> (3)
> 
> 
> At least ECL is consistent.  SBCL gets it right:
> 
> This is SBCL 2.3.2, an implementation of ANSI Common Lisp.
> * (list #+sbcl #-sbcl #+sbcl 1 2 3)
> (2 3)
> * (list #-nil #+nil #-nil 1 2 3)
> (2 3)
> 
> Allegro warns that its behavior changed between implementations, and that you should double-check to make sure that your code does what you intend.
> 
> Personally, I think this situation is a tar pit, and that nested #+ and #- reader macros should just be avoided.
> 
> rg
> 
>> On Mar 13, 2023, at 5:51 AM, Tim McNerney <mc at media.mit.edu <mailto:mc at media.mit.edu>> wrote:
>> 
>> Nice investigating. If you want my educated opinion, I think you found a misleading example (#+f #+f x y), explored it to a reasonable extent, and discovered a CCL reader bug:  
>> 
>>     (setf *features* '(:a :b :c)) followed by '(#+a #-b #+c a b c) reading as (C)
>> 
>> --Tim
>> 
>>> On Mar 13, 2023, at 06:06, Arthur Cater <arthur.cater at ucd.ie <mailto:arthur.cater at ucd.ie>> wrote:
>>> 
>>> Reading a bit of ccl’s sources I came across something that surprised me, and I thought it was neat. It was of the form
>>> 
>>>  #+feat #+feat
>>> :keyword argument
>>> 
>>> which I thought nicer than the sort of thing I’d been doing, namely  #+feat :keyword #+feat argument
>>> 
>>> 
>>> But it set me thinking, and experimenting, and now I’m puzzled, and I wonder if anyone can explain this to me.
>>> 
>>> 
>>> 
>>> ? 
>>> NIL
>>> ? (setf *features* '(:a :b :c))
>>> (:A :B :C)
>>> 
>>> ? '(#+a #+a a b c)
>>> (A B C)
>>> 
>>> ? '(#+a #-b a b c)
>>> (B C)
>>> 
>>> ? '(#+a #+b #-c a b c)
>>> (B C)
>>> 
>>> ? '(#+a #-b #+c a b c)
>>> (C)
>>> ? 
>>> 
>>> 
>>> I thought I understood what was going on until this last one. Why does #-b cause both A and B to be skipped?
>>> 
>>> Arthur
>> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.clozure.com/pipermail/openmcl-devel/attachments/20230313/2e2a672c/attachment.htm>


More information about the Openmcl-devel mailing list