Pour voir ce qui se passe ici, vous devez savoir qu'une liste dans Scheme est une chaîne récursive de paires d'éléments et d'autres listes. Toute donnée qui suit la forme d'une liste sera toujours imprimée sous forme de liste. Une fois que vous savez comment sont construites les listes de base, vous pouvez voir ce qui se passe dans votre macro.
Les paires dans Scheme peuvent être créées à l'aide de l'opérateur .
ou de la fonction cons
. Voici une simple paire de chiffres:
(quote (1 . 2))
==> '(1 . 2)
(cons 1 2)
==> '(1 . 2)
Pour créer une liste de 1 dans le schéma, vous pouvez faire une paire de quelque chose et la liste vide:
(quote (1 .()))
==> '(1)
(cons 1 (list))
==> '(1)
Une liste de 2 est une paire de quelque chose de quelque chose sur le côté gauche, et une liste de 1 sur le côté droit. De même, une liste de 3 est un élément associé à une liste de 2:
(quote (1 . (2 . (3 .()))))
==> '(1 2 3)
(cons 1 (cons 2 (cons 3 (list))))
==> '(1 2 3)
Pour voir ce que votre macro fait, vous pouvez modifier l'(quote (a b . c))
être plus explicite:
(quote (a . (b . c)))
(cons (quote a) (cons (quote b) (quote c)))
Maintenant, vous peut voir que cette forme ressemble beaucoup à quand vous construisez une liste. Si (quote c)
donne une liste, alors l'expression entière sera une liste. Dans le cas de (pair-test (1 2 3))
, c
devient (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)
Cette valeur est imprimée par le REPL comme une liste parce qu'il est une « bonne liste ». Chaque côté droit (cdr
) est une liste, tout le chemin jusqu'à la liste vide à la fin, donc cette valeur suit parfaitement la forme de la liste. Le REPL suppose que vous souhaitez voir le résultat sous forme de liste, afin qu'il soit imprimé sans .
présent.
Vous verriez '(1 2 . 3)
pour (pair-test (1 2 . 3))
, parce que c'est ainsi que le REPL imprime des "listes incorrectes". Si le dernier élément de la chaîne de paires n'est pas la liste vide, la valeur est considérée comme une "liste incorrecte" et sera imprimée différemment:
(quote (1 . (2 . 3)))
==> '(1 2 . 3)
(cons 1 (cons 2 3))
==> '(1 2 . 3)
Oui. En fait, c est '(3.()) '--- la citation supplémentaire que vous avez ne devrait pas être là --- mais vous avez essentiellement raison. –