Подтвердить что ты не робот

Используя два обратных кадра и запятые, Common Lisp

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

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

Я имею в виду, я не знаю, почему он оценил:

`(A ,3)

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

`(A 3)

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

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

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

4b9b3361

Ответ 1

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

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

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

Спецификация R5RS Scheme также включает в себя эти сведения о backticks:

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

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

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

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

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

Получается для этого (в нотации SBCL):

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

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

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

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

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

(A 3 7)

Ответ 2

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

(list 'a 3)

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

`(a ,3)

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