<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Just guessing, maybe READ-CONDITIONAL is inlined.<br class=""><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">Arthur<br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On 13 Mar 2023, at 16:14, Ron Garret <<a href="mailto:ron@flownet.com" class="">ron@flownet.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html; charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Yep, definitely a bug. CCL's behavior is inconsistent:<div class=""><br class=""></div><div class=""><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">Clozure Common Lisp Version 1.12 (v1.12) DarwinX8664</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">? (list #+ccl #-ccl #+ccl 1 2 3)</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">(3)</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">? (list #-nil #+nil #-nil 1 2 3)</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">(2 3)</span></div></div><div class=""><br class=""></div><div class="">It's a really weird bug too:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">? (get-dispatch-macro-character #\# #\+)</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">#<Compiled-function CCL::READ-CONDITIONAL #x300000562BFF></span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">? (get-dispatch-macro-character #\# #\-)</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">#<Compiled-function CCL::READ-CONDITIONAL #x300000562BFF></span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">? (trace CCL::READ-CONDITIONAL)</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">NIL</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">? #+ccl 1</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">1</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">? (trace ccl::read-feature)</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">NIL</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">? #+ccl 1</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""></span><br class=""></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">0> Calling (CCL::READ-FEATURE #<CCL::RECORDING-CHARACTER-INPUT-STREAM #x3020004F2E6D>) </span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><0 CCL::READ-FEATURE returned #\+</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">1</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><br class=""></div></div><div class="">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:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">? (in-package :ccl)</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">#<Package "CCL"></span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">? (defun read-conditional (stream subchar int)</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> (print "Entering READ-CONDITIONAL")</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> (cond ((eq subchar (read-feature stream))</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> (multiple-value-bind (form note) (read-internal stream t nil t)</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> (values form (and note (list note)))))</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> (t (let* ((*read-suppress* t))</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> (read stream t nil t)</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> (values)))))</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">;Compiler warnings :</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">; In READ-CONDITIONAL: Unused lexical variable INT</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">READ-CONDITIONAL</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">? #+ccl 1</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""></span><br class=""></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">0> Calling (READ-FEATURE #<RECORDING-CHARACTER-INPUT-STREAM #x3020004E03BD>) </span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><0 READ-FEATURE returned #\+</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">1</span></div></div><div class=""><br class=""></div><div class="">This is apparently a common bug. ECL gets it wrong too:<div class=""><br class=""></div><div class=""><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">ECL (Embeddable Common-Lisp) 21.2.1 (git:UNKNOWN)</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">> (list #+ecl #-ecl #+ecl 1 2 3)</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">(3)</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">> (list #-nil #+nil #-nil 1 2 3)</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">(3)</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><br class=""></div></div><div class=""><span style="font-variant-ligatures: no-common-ligatures" class="">At least ECL is consistent. SBCL gets it right:</span></div><div class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div><div class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">This is SBCL 2.3.2, an implementation of ANSI Common Lisp.</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">* (list #+sbcl #-sbcl #+sbcl 1 2 3)</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">(2 3)</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">* (list #-nil #+nil #-nil 1 2 3)</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">(2 3)</span></div></span></div><div class=""><br class=""></div><div class="">Allegro warns that its behavior changed between implementations, and that you should double-check to make sure that your code does what you intend.</div><div class=""><br class=""></div><div class="">Personally, I think this situation is a tar pit, and that nested #+ and #- reader macros should just be avoided.</div><div class=""><br class=""></div><div class="">rg<br class=""><div class=""><br class=""><blockquote type="cite" class=""><div class="">On Mar 13, 2023, at 5:51 AM, Tim McNerney <<a href="mailto:mc@media.mit.edu" class="">mc@media.mit.edu</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">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: <br class=""><br class=""> (setf *features* '(:a :b :c)) followed by '(#+a #-b #+c a b c) reading as (C)<br class=""><br class="">--Tim<br class=""><br class=""><blockquote type="cite" class="">On Mar 13, 2023, at 06:06, Arthur Cater <<a href="mailto:arthur.cater@ucd.ie" class="">arthur.cater@ucd.ie</a>> wrote:<br class=""><br class="">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<br class=""><br class=""> #+feat #+feat<br class=""> :keyword argument<br class=""><br class="">which I thought nicer than the sort of thing I’d been doing, namely #+feat :keyword #+feat argument<br class=""><br class=""><br class="">But it set me thinking, and experimenting, and now I’m puzzled, and I wonder if anyone can explain this to me.<br class=""><br class=""><br class=""><br class="">? <br class="">NIL<br class="">? (setf *features* '(:a :b :c))<br class="">(:A :B :C)<br class=""><br class="">? '(#+a #+a a b c)<br class="">(A B C)<br class=""><br class="">? '(#+a #-b a b c)<br class="">(B C)<br class=""><br class="">? '(#+a #+b #-c a b c)<br class="">(B C)<br class=""><br class="">? '(#+a #-b #+c a b c)<br class="">(C)<br class="">? <br class=""><br class=""><br class="">I thought I understood what was going on until this last one. Why does #-b cause both A and B to be skipped?<br class=""><br class="">Arthur<br class=""></blockquote><br class=""></div></div></blockquote></div><br class=""></div></div></div></div></blockquote></div><br class=""></div></body></html>