Непоследовательность с последовательностями Clojure?

Clojure:

1:13 user=> (first (conj '(1 2 3) 4))
4
1:14 user=> (first (conj [1 2 3] 4))
1
; . . .
1:17 user=> (first (conj (seq [1 2 3]) 4))
4

Я понимаю, что происходит, но должно ли это работать по-другому?

Ответ 1

Документация для conj (из clojure.org):

Conj [ойн]. Возвращает новую коллекцию с xs "Добавил". (элемент коннекта) возвращает (элемент). "Добавление" может происходят в разных "местах" в зависимости от конкретного типа.

Более эффективно "добавлять" элементы в конец вектора, в то время как более эффективно это делать в начале списков. conj использует то, что наиболее эффективно для структуры данных, которую вы им предоставляете.

В примерах, которые вы даете, '(1 2 3) и (seq [1 2 3]) реализуют ISeq (см. документацию для seq?), а [1 2 3] doesn ' т.

Clojure conj в конечном итоге вызывает метод cons (не путать с функцией cons - этот метод является внутренним кодом clojure) в базовой структуре данных; для векторов (PersistentVector), cons добавляет элементы в конец, тогда как для списков они добавляются к фронту (метод cons для PersistentList возвращает новый список с новым элементом в качестве главы, и существующий список как его хвост).

Ответ 2

Если вы посмотрите Clojure Структуры данных

вы увидите, что conj работает по-разному со списками и векторами.

conj помещает добавленный элемент в начало списка и в конец вектора.

Я также предлагаю посмотреть Clojure API conj

который имеет несколько хороших примеров. В большинстве приложений ClojureDocs есть несколько хороших примеров для большинства команд Clojure.