Previous: , Up: Quoting   [Contents][Index]


14.4.4 Nested quoting

Simple nested quotations have already been used throughout this section. Indeed, function quoting and symbol quoting may be used combined in order and any nesting level. Trying to quote of a self-evaluating or special form necessarily leads to double quoting it. Thus ''?a will become (quote ?a).

Furthermore, we have already seen that backquoting empowers us to create a mixture of quoted and evaluated parts of an expression. We shall now look at the various oddities which may arise particularly in nested quotation scenarios.

(setq y 'x
      x 'y)
`(,y `(,y ,@(+ 2 3)) ,@(+ 2 3))
  ⇒ (x (bq-list* y (+ 2 3)) . 5)

`(,y ,`(,y ,@(+ 2 3)) ,@(+ 2 3))
  => (x (x . 5) . 5)

`(,y ,'`(,y ,@(+ 2 3)) ,@(+ 2 3))
  ⇒ (x (backquote ((\, y) (\, (+ 2 3)))) . 5)

In the first example, you can behold the dequoting strategy of nested backquotes. Like other lisp implementations and dialects the nested structure is somewhat preserved. Substitutions are made only for dequoted (or marked as such) elements appearing at the same nesting level as the outermost backquote. But evaluation takes place at all nesting levels likewise. Inner backquote lists are evaluated but remain quoted within the outer backquote list unless these are marked themselves for dequoting and substitution. For your information, the bq-list* macro behaves like Common Lisp’s list* form.

Evaluation of the inner expression yields:

(bq-list* y (+ 2 3))
  ⇒ (x . 5)

This evaluation explains the second example.

Sometimes it is useful to leave inner backquote lists entirely untouched, for example in macros which in turn define other macros which then use backquote lists in their definition. Example 3 demonstrates how this can be achieved.

Dequoting across nesting bounds

There is no definite concept (yet). You will achieve what you want if you carefully quote your expressions. Although you need to use the expanded names for `, ,, ,@ and ,..

(let ((y 'x)
      (x 'y))
  `(,y (,'backquote (,y  ,',y))))
  ⇒ (x (backquote (x (\, y))))

With growing nesting complexity list constructors may well be more flexible.

(let ((y 'x)
      (x 'y))
  (list y (list 'backquote (list y '(\, y)))))
  ⇒ (x (backquote (x (\, y))))

In the future we may provide a more comprehensible concept where the above scenario would simply read `(,y ``(,y ,,y)). On the other hand you can create your own solutions of backquotations using – better said abusing – the comma read-syntax. The idea is to locally make all variables self-evaluating and explicitly specify an expansion for commatised variables. To get this right, this is one method out of many and it it a matter of personal taste. The next (very) simple example merely demonstrates the idea and does not represent a concept nor a special elisp feature at all:

(let* ((x 'x)
       (y 'y)
       (,x 'top-level)
       (,y x)
       (,,x ,x)
       (,,y ,x))
  (list x y ,x ,y ,,x ,,y))

Previous: , Up: Quoting   [Contents][Index]