[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Backquote idioms



    Received: from GODOT by AQUINAS via CHAOS with CHAOS-MAIL; Tue 21-May-85 22:44:45-EDT
    Received: from MIT-MC (mit-mc.arpa.ARPA) by THINK.ARPA id AA13184; Tue, 21 May 85 22:34:23 edt
    Date: Tue, 21 May 85 22:34:20 EST
    From: Alan Bawden <ALAN@MIT-MC@think>
    Subject:  Backquote idioms
    To: JAR@MIT-MC
    Cc: GLS@MIT-MC
    In-Reply-To: Msg of Tue 21 May 85 12:39:38 EST from Jonathan A Rees <JAR>
    Message-Id: <[MIT-MC].513387.850521.ALAN>

	Date: Tue, 21 May 85 12:39:38 EST
	From: Jonathan A Rees <JAR>
	    Date: Monday, 20 May 1985, 10:48-EDT
	    From: Guy Steele <gls at AQUINAS>
	    Much to my surprise, I find that
	    (a)  ,,@  *is* supported by Common Lisp.
	    (b)  ,,@  is equivalent to  ,@(list ,@

	Alan told me that  `(,b)  was allowed to expand to  (cons b nil) , which
	would cause ,,@ to not work:  ``(,,@x)  ==>  `(cons ,@x nil)
	I don't have my CLTL handy, so I can't check this.

    Steele is right!  I have been making fun of the crazy grammar that the CL
    book uses to explain backquote expansion, but no more!  According to that
    grammar all of ",,@", ",@,", ",@,@" and ",@'," work as expected!  I didn't
    bother to work out all of the three level comma combinations, I expect they
    work too, but I can't figure out at the moment if ",@',,@" makes sense...

    We could start sending bug reports to all of the backquote implementation
    that fail to meet the CL specification.  I would predict that that would
    involve us in nit-picking discussions of the precise meaning of the list of
    "ligitimate" expansions given at the top of page 351.

My position is that the examples on page 351 are all correct, but there
should also be examples illustrating that they are not all correct if
any of the items is a ,@-d form.  I suspect that the problem in most
implementations that fail my funny example is that there is an
overzealous simplifier that is not checking for nested ,@ before
simplifying.

By the way, ',@x is not always an error!  It does make sense if x is
exactly a singleton list.  Sometimes this is useful in obscure cases.

Similarly, ,@',,@x makes sense if x is a singleton list.  See the end of
this note.

I have constructed a version of backquote that rigorously follows the
backquote grammar on pages 349-350, and then optionally applies a
simplifier of my own random device.  Here follow a bunch of examples.
For each example is shown:
	the original backquoted form
	the unsimplified expansion
	the simplified expansion
	result of applying EVAL once
	result of applying EVAL twice
	...
	result of applying EVAL as many times as there were backquotes


;;; First, some useful data for the examples.

(defun foo (x) (list 'fooed x))
(setq q '(r s))
(defun r (x) (reduce #'* x))
(setq r '(3 5))
(setq s '(4 6))


``(,,q)
(APPEND (LIST 'APPEND) (LIST (APPEND (LIST 'LIST) (LIST Q))))
(LIST 'LIST Q)
(LIST (R S))
(24)

``(,@,q)
(APPEND (LIST 'APPEND) (LIST Q))
Q
(R S)
24

``(,,@q)
(APPEND (LIST 'APPEND) (LIST (APPEND (LIST 'LIST) Q)))
(CONS 'LIST Q)
(LIST R S)
((3 5) (4 6))

``(,@,@q)
(APPEND (LIST 'APPEND) Q)
(CONS 'APPEND Q)
(APPEND R S)
(3 5 4 6)


`(foo `(bar ,,q))
(APPEND (LIST 'FOO)
        (LIST (APPEND (LIST 'APPEND)
                      (LIST (APPEND (LIST 'LIST) (LIST (APPEND (LIST 'QUOTE) (LIST 'BAR)))))
                      (LIST (APPEND (LIST 'LIST) (LIST Q))))))
(LIST 'FOO (LIST 'LIST '(QUOTE BAR) Q))
(FOO (LIST (QUOTE BAR) (R S)))
(FOOED (BAR 24))

`(foo `(bar ,@,q))
(APPEND (LIST 'FOO)
        (LIST (APPEND (LIST 'APPEND)
                      (LIST (APPEND (LIST 'LIST) (LIST (APPEND (LIST 'QUOTE) (LIST 'BAR)))))
                      (LIST Q))))
(LIST 'FOO (LIST 'CONS '(QUOTE BAR) Q))
(FOO (CONS (QUOTE BAR) (R S)))
(FOOED (BAR . 24))

`(foo `(bar ,,@q))
(APPEND (LIST 'FOO)
        (LIST (APPEND (LIST 'APPEND)
                      (LIST (APPEND (LIST 'LIST) (LIST (APPEND (LIST 'QUOTE) (LIST 'BAR)))))
                      (LIST (APPEND (LIST 'LIST) Q)))))
(LIST 'FOO (LIST* 'LIST '(QUOTE BAR) Q))
(FOO (LIST (QUOTE BAR) R S))
(FOOED (BAR (3 5) (4 6)))

`(foo `(bar ,@,@q))
(APPEND (LIST 'FOO)
        (LIST (APPEND (LIST 'APPEND)
                      (LIST (APPEND (LIST 'LIST) (LIST (APPEND (LIST 'QUOTE) (LIST 'BAR)))))
                      Q)))
(LIST 'FOO (LIST 'CONS '(QUOTE BAR) (CONS 'APPEND Q)))
(FOO (CONS (QUOTE BAR) (APPEND R S)))
(FOOED (BAR 3 5 4 6))


``(,',q)
(APPEND (LIST 'APPEND) (LIST (APPEND (LIST 'LIST) (LIST (APPEND (LIST 'QUOTE) (LIST Q))))))
(LIST 'QUOTE (LIST Q))
(QUOTE ((R S)))
((R S))

``(,@',q)
(APPEND (LIST 'APPEND) (LIST (APPEND (LIST 'QUOTE) (LIST Q))))
(LIST 'QUOTE Q)
(QUOTE (R S))
(R S)


`(foo `(bar ,',q))
(APPEND (LIST 'FOO)
        (LIST (APPEND (LIST 'APPEND)
                      (LIST (APPEND (LIST 'LIST) (LIST (APPEND (LIST 'QUOTE) (LIST 'BAR)))))
                      (LIST (APPEND (LIST 'LIST) (LIST (APPEND (LIST 'QUOTE) (LIST Q))))))))
(LIST 'FOO (LIST 'QUOTE (LIST 'BAR Q)))
(FOO (QUOTE (BAR (R S))))
(FOOED (BAR (R S)))

`(foo `(bar ,@',q))
(APPEND (LIST 'FOO)
        (LIST (APPEND (LIST 'APPEND)
                      (LIST (APPEND (LIST 'LIST) (LIST (APPEND (LIST 'QUOTE) (LIST 'BAR)))))
                      (LIST (APPEND (LIST 'QUOTE) (LIST Q))))))
(LIST 'FOO (LIST 'QUOTE (CONS 'BAR Q)))
(FOO (QUOTE (BAR R S)))
(FOOED (BAR R S))

`(foo `(bar ',',q))
(APPEND
 (LIST 'FOO)
 (LIST (APPEND (LIST 'APPEND)
               (LIST (APPEND (LIST 'LIST) (LIST (APPEND (LIST 'QUOTE) (LIST 'BAR)))))
               (LIST (APPEND (LIST 'LIST)
                             (LIST (APPEND (LIST 'APPEND)
                                           (LIST (APPEND (LIST 'LIST)
                                                         (LIST (APPEND (LIST 'QUOTE)
                                                                       (LIST 'QUOTE)))))
                                           (LIST (APPEND (LIST 'LIST)
                                                         (LIST (APPEND (LIST 'QUOTE)
                                                                       (LIST Q))))))))))))
(LIST 'FOO (LIST 'QUOTE (LIST 'BAR (LIST 'QUOTE Q))))
(FOO (QUOTE (BAR (QUOTE (R S)))))
(FOOED (BAR (QUOTE (R S))))


```(,@',,@q)				;Alan's example
(APPEND (LIST 'APPEND)
        (LIST (APPEND (LIST 'LIST) (LIST (APPEND (LIST 'QUOTE) (LIST 'APPEND)))))
        (LIST (APPEND (LIST 'LIST)
                      (LIST (APPEND (LIST 'APPEND)
                                    (LIST (APPEND (LIST 'LIST)
                                                  (LIST (APPEND (LIST 'QUOTE)
                                                                (LIST 'QUOTE)))))
                                    (LIST (APPEND (LIST 'LIST) Q)))))))
(LIST* 'LIST '(QUOTE QUOTE) Q)
(LIST (QUOTE QUOTE) R S)
(QUOTE (3 5) (4 6))
<error>					;but would be sensible if Q were the singleton list (R),
					; in which case third evaluation would produce (3 5).

Do you all believe these?

--Guy