Поведение без кавычек при использовании предпоследнего символа в правильном списке, заключенном в квазикавычки

Я пытаюсь создать список (1 unquote 2), используя квазицитаты. Я пробовал это:

`(1 unquote 2)

Однако в Racket, MIT Scheme и Chez Scheme я получаю пунктирный список: '(1 . 2).

Итак, я попробовал это:

`(1 'unquote 2)

Однако я получаю (1 'unquote 2).

Наконец-то я получил список, который хотел, используя эту технику:

`(1 unquote 2 ,((lambda (x) x) 'unquote) 2)  ; Returns: '(1 unquote 2)

Почему я получаю точечный список из правильного списка в квазикавычках, когда unquote является предпоследним элементом в списке в квазикавычках?

На самом деле, он не всегда создает точечный список. Например:

`(1 unquote (list 2 3 4))  ; Returns: '(1 2 3 4)

Пожалуйста, объясните это странное поведение без кавычек, когда это предпоследний элемент в квазикавычках.


person Flux    schedule 19.01.2021    source источник


Ответы (3)


(a b c) — это сокращение от (a . (b . (c . ()))).

Так что (quasiquote (1 unquote 2)) на самом деле (quasiquote (1 . (unquote 2))), то есть '(1 . 2).

(Или, если вы хотите полностью расширить его, (quasiquote (1 unquote 2)) это (quasiquote . ((1 . (unquote . (2 . ()))) . ())))

Точно так же (quasiquote (1 unquote (list 2 3 4))) на самом деле (quasiquote (1 . (unquote (list 2 3 4)))) = (quasiquote (1 . (2 3 4))) = '(1 2 3 4).

Кстати, более простой способ создать '(1 unquote 2) с помощью квазицитата:

`(1 ,'unquote 2)
person Sorawee Porncharoenwase    schedule 19.01.2021

Согласно R5RS,

Если какой-либо из символов quasiquote, unquote или unquote-splicing появится в ‹шаблоне qq› в позициях, отличных от описанных выше, может произойти непредсказуемое поведение.

И ваши должности не такие, как описано выше - форма должна быть (unquote expression ...).

Он был обновлен до нарушения синтаксиса в R6RS.

person molbdnilo    schedule 19.01.2021
comment
Во-первых, это артефакт печати; посмотрите на его car, cadr и caddr. У меня нет времени исследовать другой вопрос для вас. - person molbdnilo; 19.01.2021

[пишу ответ, а не комментарий, потому что невозможно правильно отформатировать обратные кавычки в комментарии. Lisp/Scheme по-прежнему справляется с этим лучше, чем уценка ;-) ]

Как объяснили другие (особенно Sorawee), unquote (он же ,) — это специальное имя, которое обрабатывается особым образом, когда находится внутри списка quasiquoted (он же обратная кавычка). Чтобы предотвратить его специальное значение, есть простой обходной путь — убедиться, что специальное имя не отображается в тексте. Обратите внимание, что unquote не имеет специального значения внутри quote (в отличие от quasiquote).

Таким образом, это будет работать во всех вариантах схемы:

(define unquote-sym 'unquote) ; `unquote` is inside `quote`, so it's a mere symbol here

`(1 ,unquote-sym 2) ; '(1 unquote 2)
person Metaxal    schedule 21.01.2021
comment
Хорошо, оказывается, что перед обратным апострофом нужно поставить антислэш ` в уценке SO - person Metaxal; 21.01.2021
comment
Пожалуйста, прочитайте мой ответ на Как избежать обратной кавычки ` внутри встроенного кода в Markdown? - person Flux; 21.01.2021