(not = (тип `(1)) (тип` (1 2))) ;; Зачем? (список отдельных элементов, синтаксическая кавычка, Cons, PersistentList) - PullRequest
9 голосов
/ 09 марта 2012

Я вижу это поведение в Clojure 1.2.1:

user=> (type '(1 2))
clojure.lang.PersistentList
user=> (type `(1 2)) ;; notice syntax-quote
clojure.lang.Cons
user=> (type '(1))
clojure.lang.PersistentList
user=> (type `(1))
clojure.lang.PersistentList

Я ожидал, что `(1) будет таким же минусом, как` (1 2).

Я тоже пробовал:

user=> (type (cons 1 nil)) 
clojure.lang.PersistentList
user=> (type (cons 1 `()))
clojure.lang.Cons
user=> (type (cons 1 '()))
clojure.lang.Cons
user=> (type (cons 1 []))
clojure.lang.Cons

Так в чем причина того, что `(1) и (минусы 1 ноль) должны быть PersistentLists?

Ответы [ 2 ]

4 голосов
/ 09 марта 2012

Как говорит Амаллой, вы должны программировать не против этих точных типов, а против абстракции seq.

Однако я думаю, что могу предположить причину.Формы Clojure, которые в конечном итоге вызывают PersistentList, вызывают RT.java , в частности, метод cons(Object x, Object coll).Он начинается с довольно странной проверки: if(coll == null) return new PersistentList(x), после чего он создает объект Cons, если эта проверка не проходит.Если вы посмотрите на более ранние версии кода , вы можете найти это:

static public IPersistentCollection cons(Object x, IPersistentCollection y) {
    if(y == null)
        return new PersistentList(x);
    return y.cons(x);
}

Итак, в более ранней версии функции вызов был отправлен в метод consвторой аргумент, поэтому случай, когда вторым аргументом был null (т.е. nil в Clojure), требовалась специальная обработка.Более поздние версии не выполняют эту диспетчеризацию (или фактически делают это, но другим способом, предположительно для поддержки большего разнообразия типов коллекций), но проверка была сохранена, поскольку она не нарушает никакого правильно написанного кода.

4 голосов
/ 09 марта 2012

Если вы заботитесь о разнице, ваша программа неверна. Они оба seqs, в том смысле, что (seq? x) возвращает true; остальное - детали реализации, от которых вы не должны зависеть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...