[Openmcl-devel] multiple read-time conditionals, puzzlement
Ron Garret
ron at flownet.com
Mon Mar 13 09:14:23 PDT 2023
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> 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> 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/d0f2c46d/attachment-0001.htm>
More information about the Openmcl-devel
mailing list