要了解這裏發生了什麼,您需要知道Scheme中的列表是元素對和其他列表的遞歸鏈。任何遵循列表形式的數據將始終打印爲列表。一旦你知道了基本列表是如何構建的,你將能夠看到你的宏中發生了什麼。
Scheme中的對可以使用.
運算符或使用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)
是的。其實c是'(3。())'---你所擁有的額外引號應該不存在---但你基本上是正確的。 –