[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