За да видите какво се случва тук, трябва да знаете, че списъкът в Scheme е рекурсивна верига от двойки елементи и други списъци. Всички данни, които следват формата на списък, винаги ще бъдат отпечатани като списък. След като разберете как са изградени основните списъци, ще можете да видите какво се случва във вашия макрос.
Двойките в Scheme могат да бъдат създадени с помощта на оператора .
или с помощта на функцията cons
. Ето една проста двойка числа:
(quote (1 . 2))
==> '(1 . 2)
(cons 1 2)
==> '(1 . 2)
За да създадете списък от 1 в Scheme, можете да направите двойка от нещо и празния списък:
(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)
person
Dan Cecile
schedule
28.08.2011