Using two backquotes and commas, Common Lisp
I'm learning common lisp and I have a problem with understanding the usage of two backquotes combined with two commas:
``(a ,,(+ 1 2))
I mean, I don't have a clue why it's evaluated to:
`(A ,3)
rather than something like that:
`(A 3)
I'm explaining myself that both commas were 'consumed' in order to evaluate two backquotes in front of the form so none of the commas should've left a开发者_如何学Cnd yet there's still one. How would look
``(a ,,(+ 1 2))
using only list and ' ?
From the specs
This is what the Common Lisp HyperSpec says about nested backticks:
If the backquote syntax is nested, the innermost backquoted form should be expanded first. This means that if several commas occur in a row, the leftmost one belongs to the innermost backquote.
The R5RS Scheme spec also includes these details about backticks:
Quasiquote forms may be nested. Substitutions are made only for unquoted components appearing at the same nesting level as the outermost backquote. The nesting level increases by one inside each successive quasiquotation, and decreases by one inside each unquotation.
Also keep in mind that only one backtick gets collapsed per evaluation, just like a regular quote, it's not recursive.
Rules in action
To see how these three details interact, let's expand your example a bit. This expression...
``(a ,,(+ 1 2) ,(+ 3 4))
Gets evaluated to this (in SBCL notation):
`(A ,3 ,(+ 3 4))
- The left backtick got collapsed, so it the
(+ 1 2)
got escaped by the matching comma (the 2nd comma, according to the HyperSpec). - On the other hand, the
(+ 3 4)
didn't have enough commas to get expanded (which is what R5RS mentions). - Only one backtick got collapsed, because backticks don't get recursively expanded.
Expanding both commas
To get rid of the other backtick, another level of evaluation is needed:
(eval ``(a ,,(+ 1 2) ,(+ 3 4)))
Both backticks are gone, and we're left with a plain list:
(A 3 7)
No, both commas were consumed. There were two levels of quoting and two levels of commas. Now there's one level of quoting and one level of commas. In fact, GNU Common Lisp (2.44.1) evaluates your expression as
(list 'a 3)
That's exactly the same thing as
`(a ,3)
but more explicitly has "evaluated" both commas.
精彩评论