conj collections clojure abstraction

collections - conj - map clojure



¿Cuál es la diferencia entre una secuencia y una colección en Clojure? (5)

Soy programador de Java y soy nuevo en Clojure. Desde diferentes lugares, vi la secuencia y la colección se utilizan en diferentes casos. Sin embargo, no tengo idea de cuál es la diferencia exacta entre ellos.

Para algunos ejemplos:

1) En la documentación de Clojure para Sequence :

The Seq interface (first coll) Returns the first item in the collection. Calls seq on its argument. If coll is nil, returns nil. (rest coll) Returns a sequence of the items after the first. Calls seq on its argument. If there are no more items, returns a logical sequence for which seq returns nil. (cons item seq) Returns a new seq where item is the first element and seq is the rest.

Como puede ver, al describir la interfaz Seq, las dos primeras funciones (first / rest) usan coll que parece indicar que es una colección, mientras que la función cons usa seq que parece indicar que esto es una secuencia.

2) Hay funciones llamadas coll? y seq? que se puede usar para probar si un valor es una colección o una secuencia. Es claro que la colección y la secuencia son diferentes.

3) En la documentación de Clojure sobre '' Collections '', se dice:

Debido a que las colecciones admiten la función seq, todas las funciones de secuencia pueden usarse con cualquier colección

¿Significa esto que todas las colecciones son secuencias?

(coll? [1 2 3]) ; => true (seq? [1 2 3]) ; => false

El código anterior me dice que no es así porque [1 2 3] es una colección pero no es una secuencia.

Creo que esta es una pregunta bastante básica para Clojure, pero no puedo encontrar un lugar que explique claramente cuál es su diferencia y cuál debería usar en diferentes casos. Cualquier comentario es apreciado.


Aquí hay algunos puntos que ayudarán a comprender la diferencia entre la recopilación y la secuencia .

  1. "Colección" y "Secuencia" son abstracciones, no una propiedad que se puede determinar a partir de un valor dado.

  2. Las colecciones son bolsas de valores.

  3. La secuencia es una estructura de datos (subconjunto de recopilación) a la que se espera acceder de forma secuencial (lineal).

La siguiente figura describe mejor la relación entre ellos:

Puedes leer más sobre esto here .


Cada secuencia es una colección, pero no todas las colecciones son una secuencia.

La función seq permite convertir una colección en una secuencia. Por ejemplo, para un mapa se obtiene una lista de sus entradas. Sin embargo, esa lista de entradas es diferente del mapa en sí.


Cualquier objeto que soporte las funciones de first núcleo y rest es una sequence .

Muchos objetos satisfacen esta interfaz y cada colección de Clojure proporciona al menos un tipo de objeto seq para recorrer su contenido mediante la función seq .

Asi que:

user> (seq [1 2 3]) (1 2 3)

Y también puedes crear una secuencia de objetos desde un map

user> (seq {:a 1 :b 2}) ([:a 1] [:b 2])

Es por eso que puede usar filter , map , for , etc. en sets maps y así sucesivamente.

Así que puedes tratar muchos objetos de colección como secuencias.

Esa es la razón por la que muchas funciones de manejo de secuencias, como la llamada de filter en la entrada:

(defn filter "Returns a lazy sequence of the items in coll for which (pred item) returns true. pred must be free of side-effects." {:added "1.0" :static true} ([pred coll] (lazy-seq (when-let [s (seq coll)]

Si llamas (filter pred 5)

Don''t know how to create ISeq from: java.lang.Long RT.java:505 clojure.lang.RT.seqFrom RT.java:486 clojure.lang.RT.seq core.clj:133 clojure.core/seq core.clj:2523 clojure.core/filter[fn]

Verá que la llamada seq es el objeto es una validación de secuencia .

La mayoría de estas cosas se encuentran en el capítulo 5 de Joy of Clojure si quieres profundizar.


En Clojure for the brave and true el autor lo resume de una manera realmente comprensible:

La abstracción de la colección está estrechamente relacionada con la abstracción de la secuencia. Todas las estructuras de datos centrales de Clojure (vectores, mapas, listas y conjuntos) participan en ambas abstracciones.

Las abstracciones difieren en que la abstracción de la secuencia es "sobre" la operación de los miembros individualmente, mientras que la abstracción de la colección es "sobre" la estructura de datos en su conjunto. Por ejemplo, las funciones de colección count , empty? , y every? no se trata de ningún elemento individual; son sobre el todo


Para seq? :

Devuelve true si x implementa ISeq

Para coll? :

Devuelve true si x implementa IPersistentCollection

Y encontré que la interfaz ISeq se extiende desde IPersistentCollection en el código fuente de Clojure, por lo que, como dijo Rörd, cada secuencia es una colección.