Как работает ,',z
:
`(list ,x `(,',z ,,@y))))
^ ^
| `- this comma
`- belongs to this backquote
Приведенная выше запятая интерполирует во внутреннюю кавычку выражение ',z
или (quote ,z)
. А это ,z
, в свою очередь, принадлежит внешней обратной цитате.
Таким образом, значение z
вставляется в (quote ,z)
, чтобы сделать (quote <value-of-z>)
.
Тогда, фактически, внутренняя обратная цитата ведет себя как `(,'<value-of-z>)
.
Конкретно, предположим, что z
содержит список (+ 2 2)
. Тогда мы можем понять это с точки зрения внешней обратной кавычки, вставляющей (+ 2 2)
во внутреннюю, чтобы получить `(,'(+ 2 2) ...)
. Теперь это легко понять: когда внутренняя обратная кавычка оценивается, (+ 2 2)
защищается от оценки, в результате чего получается объект ((+ 2 2) ...)
.
Шаблон ,',',', ... ,',expr
используется для получения единственной оценки expr
во время оценки самой внешней обратной цитаты, так что это значение затем распространяется через любое количество раундов оценки оставшихся вложений обратной цитаты, не подвергаясь дальнейшей оценке. Здесь действует своего рода «алгебра обратных цитат», в которой «запятые и кавычки отменяются».
Вы также можете визуализировать ,',','...
как своего рода буровое долото, которое копается в слоях вложения, чтобы вы могли установить буквальное значение в любом месте структуры. Э.Г.
(defmacro super-nested-macro (arg)
`(... `(.... `(.....`(we simply want arg down here ,',',',arg)))))
Автор super-nested-macro
просто хочет вставить значение arg
в шаблон, в положение, которое скрыто в трех других обратных кавычках. Таким образом, обычный ,arg
не может быть использован: эта запятая будет неверно истолкована как принадлежащая самой внутренней обратной цитате.
Есть ли еще какие-нибудь странные крайние случаи с обратной / квази-цитатой?
Один странный крайний случай в обратном кавычке пытается слиться в точку:
`(a b c . ,@foo) ;; not allowed
`(a b c . ,foo) ;; OK: equivalent to `(a b c ,@foo)
Не уверен, как различные реализации работают с обратной кавычкой в точечной позиции:
`(a b c . `(d e f))
Это на самом деле не имеет смысла, и я подозреваю, что фактический полученный результат будет зависеть от внутренних реализаций обратной цитаты.
Не все объекты просматриваются для цитирования:
`#c(,(sin theta) ,(cos theta)) ;; Not required by ANSI CL, oops!
Это может работать через расширение реализации.