Используя две кавычки и запятые, Common Lisp - PullRequest
16 голосов
/ 26 сентября 2011

Я изучаю общий язык, и у меня есть проблема с пониманием использования двух обратных кавычек в сочетании с двумя запятыми:

``(a ,,(+ 1 2))

Я имею в виду, у меня нет понятия, почему это оценивается:

`(A ,3)

, а не что-то в этом роде:

`(A 3)

Я объясняю себе, что обе запятые были «израсходованы» для оценки двух обратных кавычек перед формой, поэтому ни одназапятые должны были остаться, и все же есть еще одна.Как бы выглядел

``(a ,,(+ 1 2))

, используя только список и '?

Ответы [ 2 ]

23 голосов
/ 26 сентября 2011

Из спецификации

Это то, что HyperSpec Common Lisp говорит о вложенных backticks :

Если синтаксис обратной цитаты вложен, самая внутренняя форма обратной кавычкидолжен быть расширен в первую очередь.Это означает, что если в строке встречается несколько запятых, самая левая из них относится к самой внутренней обратной цитате.

В спецификации схемы R5RS также содержатся эти сведения о обратных кавычках :

Квазицитатные формы могут быть вложенными.Замены сделаны только для компонентов без кавычек, появляющихся на том же уровне вложенности, что и крайняя обратная кавычка.Уровень вложенности увеличивается на единицу в каждой последующей кавычке и уменьшается на единицу в каждой не цитате.

Также имейте в виду, что только один обратный тик сворачивается за оценку, как и обычная кавычка, она не рекурсивна.

Правила в действии

Чтобы увидеть, как эти три детали взаимодействуют, давайте немного расширим ваш пример.Это выражение ...

``(a ,,(+ 1 2) ,(+ 3 4))

Получает оценку (в нотации SBCL):

`(A ,3 ,(+ 3 4))
  1. Левый тазик рухнул, так что (+ 1 2) сбежалсоответствующей запятой (запятая 2 и , в соответствии с HyperSpec).
  2. С другой стороны, у (+ 3 4) не было достаточно запятых для расширения (чтоR5RS упоминает).
  3. Свернут только один обратный удар, потому что обратные тики не расширяются рекурсивно.

Расширение обеих запятых

Чтобы избавиться от другого обратного ударанеобходим еще один уровень оценки:

(eval ``(a ,,(+ 1 2) ,(+ 3 4)))

Обе запинки исчезли, и у нас остался простой список:

(A 3 7)
2 голосов
/ 26 сентября 2011

Нет, обе запятые были использованы.Было два уровня цитирования и два уровня запятых.Теперь есть один уровень цитирования и один уровень запятых.Фактически, GNU Common Lisp (2.44.1) оценивает ваше выражение как

(list 'a 3)

Это то же самое, что и

`(a ,3)

, но более явно "оценило" обе запятые.

...