недостатки языка Common LISP создают список из двух символов, clojure недостатки требует seq к недостаткам на?

(Правовая оговорка - я знаю о значении Seqs в Clojure),

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

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

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

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

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

14
задан hawkeye 11 July 2010 в 10:58
поделиться

5 ответов

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

Clojure.org/sequences

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

clojure.lang.RT

9
ответ дан 1 December 2019 в 12:26
поделиться

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

В эти два слота cons-ячейки можно поместить ЧТО-нибудь.

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

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

6
ответ дан 1 December 2019 в 12:26
поделиться

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

3
ответ дан 1 December 2019 в 12:26
поделиться

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

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

3
ответ дан 1 December 2019 в 12:26
поделиться

Когда вы говорите

> (cons 'a 'b)

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

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

будет точечная пара (a . ( b . nil)).

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

2
ответ дан 1 December 2019 в 12:26
поделиться