2014-12-14 4 views
3

Я пытаюсь понять, как макросы clojure применяются к спискам. Меня смущает следующее:список clojure? и макросы

(defmacro islist [f] (list? f)) 
(islist (1 2)) ; true 
(islist '(1 2)) ; false 
(islist (quote (1 2))) ; true 

Ожидается ли это? Я заметил, что списки, к которым я передаю макросы, возвращают false при оценке с list? внутри макроса. То есть, второй пример особенно запутан.

+1

Вы уверены, что не хотите этого? (defmacro islist [f] '(list? ~ f)) – Bill

ответ

2

Внутри макроса '(1 2) имеет тип clojure.lang.Cons (вы можете это проверить, изменив list? на type). list? возвращает true, если операнд имеет тип clojure.lang.IPersistentList.

user=> (isa? clojure.lang.Cons clojure.lang.IPersistentList) 
false 

Причина clojure.lang.Cons появляется потому, что читатель строит ячейку минусы при расширении '(1 2) в (quote (1 2)), в то время как это не когда вы записываете из quote непосредственно как (quote (1 2)).

Возможно, вы захотите использовать seq? вместо list?.

+1

Спасибо. Вы случайно не знаете, был ли это сознательный выбор дизайна? Я был удивлен, когда работал https://gist.github.com/karansag/2b907d0d9c570552d33f, поэтому я задал этот вопрос. – karansag

Смежные вопросы