Чтобы увидеть, что здесь происходит, вам нужно знать, что список в Схеме представляет собой рекурсивную цепочку пар элементов и других списков.Любые данные, которые следуют за формой списка, всегда будут напечатаны как список.Как только вы узнаете, как создаются базовые списки, вы сможете увидеть, что происходит внутри вашего макроса.
Пары в схеме можно создать с помощью оператора .
или с помощью функции cons
.Вот простая пара чисел:
(quote (1 . 2))
==> '(1 . 2)
(cons 1 2)
==> '(1 . 2)
Чтобы создать список из 1 в схеме, вы можете создать из чего-то пару и пустой список:
(quote (1 . ()))
==> '(1)
(cons 1 (list))
==> '(1)
Список из2 является парой чего-то чего-то на левой стороне, и список 1 на правой стороне.Аналогично, список из 3 - это один элемент в паре со списком из 2:
(quote (1 . (2 . (3 . ()))))
==> '(1 2 3)
(cons 1 (cons 2 (cons 3 (list))))
==> '(1 2 3)
Чтобы увидеть, что делает ваш макрос, вы можете переставить (quote (a b . c))
так, чтобы он был более явным:
(quote (a . (b . c)))
(cons (quote a) (cons (quote b) (quote c)))
Теперь вы можете видеть, что эта форма очень похожа на то, когда вы создаете список.Если (quote c)
приводит к списку, тогда все выражение будет списком.В случае (pair-test (1 2 3))
, c
становится (3 . ())
:
(quote (a . (b . c)))
==> (quote (1 . (2 . (3 . ()))))
==> '(1 2 3)
(cons (quote a) (cons (quote b) (quote c)))
==> (cons '1 (cons '2 '(3 . ())))
==> '(1 2 3)
Это значение печатается в REPL в виде списка, поскольку это «правильный список».Каждая правая сторона (cdr
) является списком, вплоть до пустого списка в конце, поэтому это значение полностью соответствует форме списка.REPL предполагает, что вы хотели бы видеть результат в виде списка, поэтому он печатается без .
подарка.
Вы бы увидели '(1 2 . 3)
для (pair-test (1 2 . 3))
, потому что именно так REPLпечатает "неправильные списки".Если последний элемент в цепочке пар не является пустым списком, значение считается «неправильным списком» и будет напечатано иначе:
(quote (1 . (2 . 3)))
==> '(1 2 . 3)
(cons 1 (cons 2 3))
==> '(1 2 . 3)