I see that SBCL expands this way:
``(,,@'(0 1 2) ,3) -> `(,0 ,1 ,2 ,3)
so apparently the second comma is consumed while the first one is copied before each element of the spliced list.
This behavior seems peculiar to sbcl, as clisp evaluates that form to (LIST* 0 1 2 '(3)) and gcl to (LIST 0 1 2 3): they both discard the other backtick-comma pair.
I wonder what ANSI says on the matter. Does any of the two behaviors, the sbcl's and the clisp/gcl's, follows from the basic rules, for example those in http://www.lispworks.com/documentation/HyperSpec/Body/02_df.htm?
I'd appreciate any help. Thanks,
Andrea Monaco
You're thinking about this in an improper and potentially confusing way. You use words like "copy" and "discard" characters, as if this were an issue about text editing. It is not.
Backquote notation is a way of writing run-time code that fills in a certain template, allowing that code to be notated in a way more helpful and visible to the programmer than if he had to write that code himself. Your use of "evaluates" is also misleading, since the reader only READs and nothing here is EVALUATEd. It is entirely as if a backquote form is replaced by the runtime code that would have the specified result, and the ANS permits the backquote-generated replacement code to be anything that has the same effect. (However, many bq implementations expand into alternately-named equivalent internal functions, such as sys::bq-list, sys::bq-cons) so that the pretty printer can recognise bq expansions and attempt to reconstruct something equivalent to the original notation when one of these source-code forms needs be printed in a development environment.)
On Fri, Feb 10, 2023 at 12:16 PM Andrea Monaco andrea.monaco@autistici.org wrote:
I see that SBCL expands this way:
``(,,@'(0 1 2) ,3) -> `(,0 ,1 ,2 ,3)
so apparently the second comma is consumed while the first one is copied before each element of the spliced list.
This behavior seems peculiar to sbcl, as clisp evaluates that form to (LIST* 0 1 2 '(3)) and gcl to (LIST 0 1 2 3): they both discard the other backtick-comma pair.
I wonder what ANSI says on the matter. Does any of the two behaviors, the sbcl's and the clisp/gcl's, follows from the basic rules, for example those in http://www.lispworks.com/documentation/HyperSpec/Body/02_df.htm?
I'd appreciate any help. Thanks,
Andrea Monaco
Hello Andrea,
Generally ,,@ (and in a matter of fact ,@,@) are unspecified behavior because the specification says[1] that both , and ,@ operate on a FORM[2] while in these constructs they are invoked on something that under normal circumstances produces many values.
The behavior exhibited by clisp and gcl (and ecl) relies on the assumption that what appears after , (or ,@) is a form so it can transform `(,X) to (list X), hence ``(,,@X) to `(list ,@X) and that leads to (list 0 1 2 3).
Having that in mind CLtL2 book in one of appendices proposes the reader algorithm where splicing behaves the same as in SBCL. This may be a bit cumbersome if we play a fool with the reader:
CL-USER> (let ((x '(1 2 3))) (car (second ``(,@,@x)))) ,@1
Under ECL this will signal an error: ,@ or ,. has appeared in an illegal position just as you'd expect from `,@foo.
Generally recursive splicing seems more intuitive but it allows results that are not valid lisp forms. Shallow splicing on the other hand yields simpler (context-free) reader implementation and does not allow such values. All in all not having the form after comma (or comma atsign) is an UBI.
[1] http://www.lispworks.com/documentation/HyperSpec/Body/02_df.htm [2] form n. 1. any object meant to be evaluated. 2. a symbol, a compound form, or a self-evaluating object. 3. (for an operator, as in ``<<operator>> form'') a compound form having that operator as its first element. ``A quote form is a constant form.''
Best regards, Daniel
-- Daniel Kochmański ;; aka jackdaniel | Przemyśl, Poland TurtleWare - Daniel Kochmański | www.turtleware.eu
"Be the change that you wish to see in the world." - Mahatma Gandhi
------- Original Message ------- On Friday, February 10th, 2023 at 21:13, Andrea Monaco andrea.monaco@autistici.org wrote:
I see that SBCL expands this way:
``(,,@'(0 1 2) ,3) -> `(,0 ,1 ,2 ,3)
so apparently the second comma is consumed while the first one is copied before each element of the spliced list.
This behavior seems peculiar to sbcl, as clisp evaluates that form to (LIST* 0 1 2 '(3)) and gcl to (LIST 0 1 2 3): they both discard the other backtick-comma pair.
I wonder what ANSI says on the matter. Does any of the two behaviors, the sbcl's and the clisp/gcl's, follows from the basic rules, for example those in http://www.lispworks.com/documentation/HyperSpec/Body/02_df.htm?
I'd appreciate any help. Thanks,
Andrea Monaco
As Steve mentioned, the pretty printer is also involved here. Try setting *print-pretty* to nil to see what sbcl is really doing.