Common Lisp Минусы создает список из двух символов, Clojure Минусы требует Seq для минусов?

(Отказ от ответственности - я знаю о значении Seqs в Clojure)

В общем случае функция cons может использоваться для объединения двух символов в список:

(def s 'x)
(def l 'y)
(cons s l)

В clojure - вы можете использовать только против последовательности - минусы не были расширены для работы с двумя символами. Итак, вы должны написать:

(def s 'x)
(def l 'y)
(cons s '(l))

Существует ли в Clojure паттерн более высокого уровня, объясняющий эту разницу между Common LISP и Clojure?

5 ответов

Решение

В отличие от традиционных Лиспов, в Clojure списки не являются основными структурами данных. Структуры данных могут реализовывать интерфейс ISeq, который представляет собой другое представление структуры данных, которую он предоставляет, позволяя тем же функциям получать доступ к элементам в каждом из них. (Списки уже реализуют это. seq? проверяет, реализует ли что-то ISeq.(seq? '(1 2)), (seq? [1 2])) Clojure просто действует иначе (по уважительной причине), в том случае, если cons используется последовательность (это на самом деле типа clojure.lang.Cons) построен из a а также (seq b) возвращается (a будучи аргументом 1 и b arg 2) Очевидно, что символы не реализуют и не могут реализовать ISeq.

http://clojure.org/sequences

Скринкаст / разговор Ричей Хикки, однако, обратите внимание, что rest изменилось, и его предыдущее поведение теперь в nextи что lazy-cons был заменен lazy-seq а также cons,

clojure.lang.RT

В Common Lisp CONS создает так называемую ячейку CONS, которая похожа на запись с двумя слотами: "car" и "cdr".

Вы можете положить НИЧЕГО в эти два слота камеры.

Клетки минусов используются для построения списков. Но можно создать все виды структур данных с объединенными ячейками: деревья, графики, различные типы специализированных списков, ...

Реализации Lisp высоко оптимизированы, чтобы обеспечить очень эффективные cons-ячейки.

Список Lisp - это просто распространенный способ использования cons-ячеек (см . Описание Райнера). Clojure лучше всего рассматривать как отсутствие минусов (хотя нечто подобное может скрыться под капотом). Clojure cons это неправильное название, на самом деле его просто нужно назвать prepend,

В Clojure предпочтительным является использование двухэлементного вектора: [:a :b], Под капотом такие маленькие векторы реализованы как массивы Java и являются чрезвычайно простыми и быстрыми.

Короткая рука для (cons :a '(:b)) (или же (cons :a (cons :b nil))) является list: (list :a :b),

Когда ты сказал

> (cons 'a 'b)

в общем случае вы получаете не список, а пару точек: (a . b)тогда как результат

> (cons 'a (cons 'b nil))

это пунктирная пара (a . ( b . nil)),

В первом списке cdr() этого не список, так как он здесь b и не nilсоставляя неправильный список. Правильные списки должны быть прекращены nil, Поэтому функции более высокого порядка, такие как mapcar() и друзья не будут работать, но мы сохраняем камеру. Я предполагаю, что дизайнеры Clojure удалили эту функцию из-за путаницы, которую это могло вызвать.

Другие вопросы по тегам