Buscar..


Sintaxis

  • '()()
  • '(1 2 3 4 5)(1 2 3 4 5)
  • '(1 foo 2 bar 3)(1 'foo 2 'bar 3)
  • ( list 1 2 3 4 5)(1 2 3 4 5)
  • ( list* [1 2 3 4 5])(1 2 3 4 5)
  • [][]
  • [1 2 3 4 5][1 2 3 4 5]
  • ( vector 1 2 3 4 5)[1 2 3 4 5]
  • ( vec '(1 2 3 4 5))[1 2 3 4 5]
  • {} => {}
  • {:keyA 1 :keyB 2}{:keyA 1 :keyB 2}
  • {:keyA 1, :keyB 2}{:keyA 1 :keyB 2}
  • ( hash-map :keyA 1 :keyB 2){:keyA 1 :keyB 2}
  • ( sorted-map 5 "five" 1 "one"){1 "one" 5 "five"} (las entradas se ordenan por clave cuando se usan como una secuencia)
  • #{}#{}
  • #{1 2 3 4 5}#{4 3 2 5 1} (sin ordenar)
  • ( hash-set 1 2 3 4 5)#{2 5 4 1 3} (sin ordenar)
  • ( sorted-set 2 5 4 3 1)#{1 2 3 4 5}

Colecciones

Todas las colecciones de Clojure integradas son inmutables y heterogéneas, tienen una sintaxis literal y admiten las funciones conj , count y seq .

  • conj devuelve una nueva colección que es equivalente a una colección existente con un elemento "agregado", ya sea en "constante" o tiempo logarítmico. Lo que exactamente esto significa depende de la colección.
  • count devuelve el número de elementos en una colección, en tiempo constante.
  • seq devuelve nil para una colección vacía, o una secuencia de elementos para una colección no vacía, en tiempo constante.

Liza

Una lista se denota entre paréntesis:

()
;;=> ()

Una lista de Clojure es una lista enlazada individualmente . conj "combina" un nuevo elemento de la colección en la ubicación más eficiente. Para listas, esto es al principio:

(conj () :foo)
;;=> (:foo)

(conj (conj () :bar) :foo)
;;=> (:foo :bar)

A diferencia de otras colecciones, las listas no vacías se evalúan como llamadas a formularios especiales, macros o funciones cuando se evalúan. Por lo tanto, mientras que (:foo) es la representación literal de la lista que contiene :foo como su único elemento, evaluar (:foo) en un REPL provocará que se IllegalArgumentException una IllegalArgumentException porque una palabra clave no puede invocarse como una función nula .

(:foo)
;; java.lang.IllegalArgumentException: Wrong number of args passed to keyword: :foo

Para evitar que Clojure evalúe una lista no vacía, puede quote :

'(:foo)
;;=> (:foo)

'(:foo :bar)
;;=> (:foo :bar)

Desafortunadamente, esto hace que los elementos no sean evaluados:

(+ 1 1)
;;=> 2

'(1 (+ 1 1) 3)
;;=> (1 (+ 1 1) 3)

Por esta razón, normalmente querrá usar list , una función variadic que evalúa todos sus argumentos y utiliza esos resultados para construir una lista:

(list)
;;=> ()

(list :foo)
;;=> (:foo)

(list :foo :bar)
;;=> (:foo :bar)

(list 1 (+ 1 1) 3)
;;=> (1 2 3)

count devuelve el número de elementos, en tiempo constante:

(count ())
;;=> 0

(count (conj () :foo))
;;=> 1

(count '(:foo :bar))
;;=> 2

¿Puedes probar si algo es una lista usando la list? predicado:

(list? ())
;;=> true

(list? '(:foo :bar))
;;=> true

(list? nil)
;;=> false

(list? 42)
;;=> false

(list? :foo)
;;=> false

Puedes obtener el primer elemento de una lista usando peek :

(peek ())
;;=> nil

(peek '(:foo))
;;=> :foo

(peek '(:foo :bar))
;;=> :foo

Puedes obtener una nueva lista sin el primer elemento usando pop :

(pop '(:foo))
;;=> ()

(pop '(:foo :bar))
;;=> (:bar)

Tenga en cuenta que si intenta pop una lista vacía, obtendrá un IllegalStateException :

(pop ())
;; java.lang.IllegalStateException: Can't pop empty list

Finalmente, todas las listas son secuencias, por lo que puede hacer todo con una lista que puede hacer con cualquier otra secuencia. De hecho, con la excepción de la lista vacía, llamar a seq en una lista devuelve el mismo objeto exacto:

(seq ())
;;=> nil

(seq '(:foo))
;;=> (:foo)

(seq '(:foo :bar))
;;=> (:foo :bar)

(let [x '(:foo :bar)]
  (identical? x (seq x)))
;;=> true

Secuencias

Una secuencia es muy parecida a una lista: es un objeto inmutable que puede darle su first elemento o el rest de sus elementos en tiempo constante. También puede cons truct una nueva secuencia de una secuencia existente y un elemento para pegarse al principio.

Puedes probar si algo es una secuencia usando la secuencia seq? predicado:

(seq? nil)
;;=> false

(seq? 42)
;;=> false

(seq? :foo)
;;=> false

Como ya sabes, las listas son secuencias:

(seq? ())
;;=> true

(seq? '(:foo :bar))
;;=> true

Todo lo que obtenga al llamar a seq o rseq o las keys o vals en una colección no vacía también es una secuencia:

(seq? (seq ()))
;;=> false

(seq? (seq '(:foo :bar)))
;;=> true

(seq? (seq []))
;;=> false

(seq? (seq [:foo :bar]))
;;=> true

(seq? (rseq []))
;;=> false

(seq? (rseq [:foo :bar]))
;;=> true

(seq? (seq {}))
;;=> false

(seq? (seq {:foo :bar :baz :qux}))
;;=> true

(seq? (keys {}))
;;=> false

(seq? (keys {:foo :bar :baz :qux}))
;;=> true

(seq? (vals {}))
;;=> false

(seq? (vals {:foo :bar :baz :qux}))
;;=> true

(seq? (seq #{}))
;;=> false

(seq? (seq #{:foo :bar}))
;;=> true

Recuerde que todas las listas son secuencias, pero no todas las secuencias son listas. Mientras que las listas admiten peek y pop y count en tiempo constante, en general, una secuencia no necesita admitir ninguna de esas funciones. Si intentas llamar peek o pop en una secuencia que no es compatible con la interfaz de pila de Clojure, obtendrás una ClassCastException :

(peek (seq [:foo :bar]))
;; java.lang.ClassCastException: clojure.lang.PersistentVector$ChunkedSeq cannot be cast to clojure.lang.IPersistentStack

(pop (seq [:foo :bar]))
;; java.lang.ClassCastException: clojure.lang.PersistentVector$ChunkedSeq cannot be cast to clojure.lang.IPersistentStack

(peek (seq #{:foo :bar}))
;; java.lang.ClassCastException: clojure.lang.APersistentMap$KeySeq cannot be cast to clojure.lang.IPersistentStack

(pop (seq #{:foo :bar}))
;; java.lang.ClassCastException: clojure.lang.APersistentMap$KeySeq cannot be cast to clojure.lang.IPersistentStack

(peek (seq {:foo :bar :baz :qux}))
;; java.lang.ClassCastException: clojure.lang.PersistentArrayMap$Seq cannot be cast to clojure.lang.IPersistentStack

(pop (seq {:foo :bar :baz :qux}))
;; java.lang.ClassCastException: clojure.lang.PersistentArrayMap$Seq cannot be cast to clojure.lang.IPersistentStack

Si llama al count en una secuencia que no implementa el count en un tiempo constante, no obtendrá un error; en su lugar, Clojure recorrerá toda la secuencia hasta que llegue al final, luego devolverá el número de elementos que atravesó. Esto significa que, para secuencias generales, el count es lineal, no constante, en el tiempo. ¿Puede probar si algo admite el count tiempo constante usando el counted? predicado:

(counted? '(:foo :bar))
;;=> true

(counted? (seq '(:foo :bar)))
;;=> true

(counted? [:foo :bar])
;;=> true

(counted? (seq [:foo :bar]))
;;=> true

(counted? {:foo :bar :baz :qux})
;;=> true

(counted? (seq {:foo :bar :baz :qux}))
;;=> true

(counted? #{:foo :bar})
;;=> true

(counted? (seq #{:foo :bar}))
;;=> false

Como se mencionó anteriormente, puede usar first para obtener el primer elemento de una secuencia. Tenga en cuenta que first llamará a seq en su argumento, por lo que se puede usar en cualquier cosa "seqable", no solo en secuencias reales:

(first nil)
;;=> nil

(first '(:foo))
;;=> :foo

(first '(:foo :bar))
;;=> :foo

(first [:foo])
;;=> :foo

(first [:foo :bar])
;;=> :foo

(first {:foo :bar})
;;=> [:foo :bar]

(first #{:foo})
;;=> :foo

También como se mencionó anteriormente, puede usar el rest para obtener una secuencia que contenga todo menos el primer elemento de una secuencia existente. Como first , llama a la seq en su argumento. Sin embargo, no llama a la seq en su resultado! Esto significa que, si llama a rest en una secuencia que contiene menos de dos elementos, obtendrá back () lugar de nil :

(rest nil)
;;=> ()

(rest '(:foo))
;;=> ()

(rest '(:foo :bar))
;;=> (:bar)

(rest [:foo])
;;=> ()

(rest [:foo :bar])
;;=> (:bar)

(rest {:foo :bar})
;;=> ()

(rest #{:foo})
;;=> ()

Si desea volver a nil cuando no hay más elementos en una secuencia, puede usar next lugar de rest :

(next nil)
;;=> nil

(next '(:foo))
;;=> nil

(next [:foo])
;;=> nil

Puede usar la función cons para crear una nueva secuencia que devolverá su primer argumento para el first argumento y su segundo argumento para el rest :

(cons :foo nil)
;;=> (:foo)

(cons :foo (cons :bar nil))
;;=> (:foo :bar)

Clojure proporciona una gran biblioteca de secuencias con muchas funciones para tratar con secuencias. Lo importante de esta biblioteca es que funciona con cualquier cosa "seqable", no solo con listas. Es por eso que el concepto de una secuencia es tan útil; significa que una sola función, como reduce , funciona perfectamente en cualquier colección:

(reduce + '(1 2 3))
;;=> 6

(reduce + [1 2 3])
;;=> 6

(reduce + #{1 2 3})
;;=> 6

La otra razón por la que las secuencias son útiles es que, dado que no requieren ninguna implementación particular de first y rest , permiten secuencias perezosas cuyos elementos solo se realizan cuando es necesario.

Dada una expresión que crearía una secuencia, puede envolver esa expresión en la macro lazy-seq para obtener un objeto que actúe como una secuencia, pero solo evaluará esa expresión cuando la función seq le pida que lo haga, en en qué punto almacenará en caché el resultado de la expresión y reenviará las first y rest llamadas al resultado en caché.

Para secuencias finitas, una secuencia perezosa generalmente actúa de la misma manera que una secuencia ansiosa equivalente:

(seq [:foo :bar])
;;=> (:foo :bar)

(lazy-seq [:foo :bar])
;;=> (:foo :bar)

Sin embargo, la diferencia se hace evidente para secuencias infinitas:

(defn eager-fibonacci [a b]
  (cons a (eager-fibonacci b (+' a b))))

(defn lazy-fibonacci [a b]
  (lazy-seq (cons a (lazy-fibonacci b (+' a b)))))

(take 10 (eager-fibonacci 0 1))
;; java.lang.StackOverflowError:

(take 10 (lazy-fibonacci 0 1))
;;=> (0 1 1 2 3 5 8 13 21 34)

Vectores

Un vector se denota entre corchetes:

[]
;;=> []

[:foo]
;;=> [:foo]

[:foo :bar]
;;=> [:foo :bar]

[1 (+ 1 1) 3]
;;=> [1 2 3]

Además de usar la sintaxis literal, también puede usar la función vector para construir un vector:

(vector)
;;=> []

(vector :foo)
;;=> [:foo]

(vector :foo :bar)
;;=> [:foo :bar]

(vector 1 (+ 1 1) 3)
;;=> [1 2 3]

¿Puedes probar si algo es un vector usando el vector? predicado:

(vector? [])
;;=> true

(vector? [:foo :bar])
;;=> true

(vector? nil)
;;=> false

(vector? 42)
;;=> false

(vector? :foo)
;;=> false

conj agrega elementos al final de un vector:

(conj [] :foo)
;;=> [:foo]

(conj (conj [] :foo) :bar)
;;=> [:foo :bar]

(conj [] :foo :bar)
;;=> [:foo :bar]

count devuelve el número de elementos, en tiempo constante:

(count [])
;;=> 0

(count (conj [] :foo))
;;=> 1

(count [:foo :bar])
;;=> 2

Puedes obtener el último elemento de un vector usando peek :

(peek [])
;;=> nil

(peek [:foo])
;;=> :foo

(peek [:foo :bar])
;;=> :bar

Puedes obtener un nuevo vector sin el último elemento usando pop :

(pop [:foo])
;;=> []

(pop [:foo :bar])
;;=> [:foo]

Tenga en cuenta que si intenta IllegalStateException un vector vacío, obtendrá una IllegalStateException :

(pop [])
;; java.lang.IllegalStateException: Can't pop empty vector

A diferencia de las listas, los vectores están indexados. Puede obtener un elemento de un vector por índice en tiempo "constante" usando get :

(get [:foo :bar] 0)
;;=> :foo

(get [:foo :bar] 1)
;;=> :bar

(get [:foo :bar] -1)
;;=> nil

(get [:foo :bar] 2)
;;=> nil

Además, los vectores en sí mismos son funciones que toman un índice y devuelven el elemento en ese índice:

([:foo :bar] 0)
;;=> :foo

([:foo :bar] 1)
;;=> :bar

Sin embargo, si llama a un vector con un índice no válido, obtendrá una IndexOutOfBoundsException lugar de nil :

([:foo :bar] -1)
;; java.lang.IndexOutOfBoundsException:

([:foo :bar] 2)
;; java.lang.IndexOutOfBoundsException:

Puede obtener un nuevo vector con un valor diferente en un índice particular usando assoc :

(assoc [:foo :bar] 0 42)
;;=> [42 :bar]

(assoc [:foo :bar] 1 42)
;;=> [:foo 42]

Si pasa un índice igual al count del vector, Clojure agregará el elemento como si hubiera usado conj . Sin embargo, si pasa un índice que es negativo o mayor que el count , obtendrá una IndexOutOfBoundsException :

(assoc [:foo :bar] 2 42)
;;=> [:foo :bar 42]

(assoc [:foo :bar] -1 42)
;; java.lang.IndexOutOfBoundsException:

(assoc [:foo :bar] 3 42)
;; java.lang.IndexOutOfBoundsException:

Puede obtener una secuencia de los elementos en un vector usando seq :

(seq [])
;;=> nil

(seq [:foo])
;;=> (:foo)

(seq [:foo :bar])
;;=> (:foo :bar)

Dado que los vectores están indexados, también puede obtener una secuencia invertida de los elementos de un vector utilizando rseq :

(rseq [])
;;=> nil

(rseq [:foo])
;;=> (:foo)

(rseq [:foo :bar])
;;=> (:bar :foo)

Tenga en cuenta que, aunque todas las listas son secuencias, y las secuencias se muestran de la misma manera que las listas, ¡no todas las secuencias son listas!

'(:foo :bar)
;;=> (:foo :bar)

(seq [:foo :bar])
;;=> (:foo :bar)

(list? '(:foo :bar))
;;=> true

(list? (seq [:foo :bar]))
;;=> false

(list? (rseq [:foo :bar]))
;;=> false

Conjuntos

Al igual que los mapas, los conjuntos son asociativos y desordenados. A diferencia de los mapas, que contienen asignaciones de claves a valores, los conjuntos se asignan esencialmente de las claves a sí mismos.

Un conjunto se denota con llaves, precedido por un octothorpe:

#{}
;;=> #{}

#{:foo}
;;=> #{:foo}

#{:foo :bar}
;;=> #{:bar :foo}

Al igual que con los mapas, el orden en que aparecen los elementos en un conjunto literal no importa:

(= #{:foo :bar} #{:bar :foo})
;;=> true

¿Puedes probar si algo es un conjunto usando el set? predicado:

(set? #{})
;;=> true

(set? #{:foo})
;;=> true

(set? #{:foo :bar})
;;=> true

(set? nil)
;;=> false

(set? 42)
;;=> false

(set? :foo)
;;=> false

Puede probar si un mapa contiene un ítem dado en tiempo "constante" usando los contains? predicado:

(contains? #{} :foo)
;;=> false

(contains? #{:foo} :foo)
;;=> true

(contains? #{:foo} :bar)
;;=> false

(contains? #{} nil)
;;=> false

(contains? #{nil} nil)
;;=> true

Además, los propios conjuntos son funciones que toman un elemento y devuelven ese elemento si está presente en el conjunto, o nil si no lo está:

(#{} :foo)
;;=> nil

(#{:foo} :foo)
;;=> :foo

(#{:foo} :bar)
;;=> nil

(#{} nil)
;;=> nil

(#{nil} nil)
;;=> nil

Puede usar conj para obtener un conjunto que tenga todos los elementos de un conjunto existente, más un elemento adicional:

(conj #{} :foo)
;;=> #{:foo}

(conj (conj #{} :foo) :bar)
;;=> #{:bar :foo}

(conj #{:foo} :foo)
;;=> #{:foo}

Puede usar disj para obtener un conjunto que tenga todos los elementos de un conjunto existente, menos un elemento:

(disj #{} :foo)
;;=> #{}

(disj #{:foo} :foo)
;;=> #{}

(disj #{:foo} :bar)
;;=> #{:foo}

(disj #{:foo :bar} :foo)
;;=> #{:bar}

(disj #{:foo :bar} :bar)
;;=> #{:foo}

count devuelve el número de elementos, en tiempo constante:

(count #{})
;;=> 0

(count (conj #{} :foo))
;;=> 1

(count #{:foo :bar})
;;=> 2

Puede obtener una secuencia de todos los elementos en un conjunto utilizando seq :

(seq #{})
;;=> nil

(seq #{:foo})
;;=> (:foo)

(seq #{:foo :bar})
;;=> (:bar :foo)

Mapas

A diferencia de la lista, que es una estructura de datos secuencial, y el vector, que es a la vez secuencial y asociativo, el mapa es exclusivamente una estructura de datos asociativa. Un mapa consiste en un conjunto de asignaciones de claves a valores. Todas las claves son únicas, por lo que los mapas admiten la búsqueda en tiempo "constante" de las claves a los valores.

Un mapa se denota con llaves:

{}
;;=> {}

{:foo :bar}
;;=> {:foo :bar}

{:foo :bar :baz :qux}
;;=> {:foo :bar, :baz :qux}

Cada par de dos elementos es un par clave-valor. Entonces, por ejemplo, el primer mapa de arriba no tiene mapeos. El segundo tiene un mapeo, desde la clave :foo hasta el valor :bar . El tercero tiene dos asignaciones, una de la clave :foo al valor :bar , y una de la clave :baz al valor :qux . Los mapas están intrínsecamente desordenados, por lo que el orden en el que aparecen las asignaciones no importa:

(= {:foo :bar :baz :qux}
   {:baz :qux :foo :bar})
;;=> true

¿Puedes probar si algo es un mapa usando el map? predicado:

(map? {})
;;=> true

(map? {:foo :bar})
;;=> true

(map? {:foo :bar :baz :qux})
;;=> true

(map? nil)
;;=> false

(map? 42)
;;=> false

(map? :foo)
;;=> false

¿Puede probar si un mapa contiene una clave dada en tiempo "constante" usando los contains? predicado:

(contains? {:foo :bar :baz :qux} 42)
;;=> false

(contains? {:foo :bar :baz :qux} :foo)
;;=> true

(contains? {:foo :bar :baz :qux} :bar)
;;=> false

(contains? {:foo :bar :baz :qux} :baz)
;;=> true

(contains? {:foo :bar :baz :qux} :qux)
;;=> false

(contains? {:foo nil} :foo)
;;=> true

(contains? {:foo nil} :bar)
;;=> false

Puede obtener el valor asociado con una clave usando get :

(get {:foo :bar :baz :qux} 42)
;;=> nil

(get {:foo :bar :baz :qux} :foo)
;;=> :bar

(get {:foo :bar :baz :qux} :bar)
;;=> nil

(get {:foo :bar :baz :qux} :baz)
;;=> :qux

(get {:foo :bar :baz :qux} :qux)
;;=> nil

(get {:foo nil} :foo)
;;=> nil

(get {:foo nil} :bar)
;;=> nil

Además, los mapas en sí mismos son funciones que toman una clave y devuelven el valor asociado con esa clave:

({:foo :bar :baz :qux} 42)
;;=> nil

({:foo :bar :baz :qux} :foo)
;;=> :bar

({:foo :bar :baz :qux} :bar)
;;=> nil

({:foo :bar :baz :qux} :baz)
;;=> :qux

({:foo :bar :baz :qux} :qux)
;;=> nil

({:foo nil} :foo)
;;=> nil

({:foo nil} :bar)
;;=> nil

Puede obtener una entrada completa del mapa (clave y valor juntos) como un vector de dos elementos usando find :

(find {:foo :bar :baz :qux} 42)
;;=> nil

(find {:foo :bar :baz :qux} :foo)
;;=> [:foo :bar]

(find {:foo :bar :baz :qux} :bar)
;;=> nil

(find {:foo :bar :baz :qux} :baz)
;;=> [:baz :qux]

(find {:foo :bar :baz :qux} :qux)
;;=> nil

(find {:foo nil} :foo)
;;=> [:foo nil]

(find {:foo nil} :bar)
;;=> nil

Puede extraer la clave o el valor de una entrada de mapa usando key o val , respectivamente:

(key (find {:foo :bar} :foo))
;;=> :foo

(val (find {:foo :bar} :foo))
;;=> :bar

Tenga en cuenta que, aunque todas las entradas del mapa de Clojure son vectores, no todos los vectores son entradas del mapa. Si intenta llamar a key o val en algo que no sea una entrada de mapa, obtendrá una ClassCastException :

(key [:foo :bar])
;; java.lang.ClassCastException:

(val [:foo :bar])
;; java.lang.ClassCastException:

¿Puede probar si algo es una entrada de mapa usando la map-entry? predicado:

(map-entry? (find {:foo :bar} :foo))
;;=> true

(map-entry? [:foo :bar])
;;=> false

Puede usar assoc para obtener un mapa que tenga todos los mismos pares clave-valor que un mapa existente, con un mapa agregado o modificado:

(assoc {} :foo :bar)
;;=> {:foo :bar}

(assoc (assoc {} :foo :bar) :baz :qux)
;;=> {:foo :bar, :baz :qux}

(assoc {:baz :qux} :foo :bar)
;;=> {:baz :qux, :foo :bar}

(assoc {:foo :bar :baz :qux} :foo 42)
;;=> {:foo 42, :baz :qux}

(assoc {:foo :bar :baz :qux} :baz 42)
;;=> {:foo :bar, :baz 42}

Puede usar dissoc para obtener un mapa que tenga todos los mismos pares clave-valor que un mapa existente, con posiblemente un mapa eliminado:

(dissoc {:foo :bar :baz :qux} 42)
;;=> {:foo :bar :baz :qux}

(dissoc {:foo :bar :baz :qux} :foo)
;;=> {:baz :qux}

(dissoc {:foo :bar :baz :qux} :bar)
;;=> {:foo :bar :baz :qux}

(dissoc {:foo :bar :baz :qux} :baz)
;;=> {:foo :bar}

(dissoc {:foo :bar :baz :qux} :qux)
;;=> {:foo :bar :baz :qux}

(dissoc {:foo nil} :foo)
;;=> {}

count devuelve el número de mapeos, en tiempo constante:

(count {})
;;=> 0

(count (assoc {} :foo :bar))
;;=> 1

(count {:foo :bar :baz :qux})
;;=> 2

Puede obtener una secuencia de todas las entradas en un mapa usando seq :

(seq {})
;;=> nil

(seq {:foo :bar})
;;=> ([:foo :bar])

(seq {:foo :bar :baz :qux})
;;=> ([:foo :bar] [:baz :qux])

Nuevamente, los mapas no están ordenados, por lo que el orden de los elementos en una secuencia que se obtiene al llamar a seq en un mapa no está definido.

Usted puede obtener una secuencia de sólo las teclas o sólo los valores en un mapa utilizando keys o vals , respectivamente:

(keys {})
;;=> nil

(keys {:foo :bar})
;;=> (:foo)

(keys {:foo :bar :baz :qux})
;;=> (:foo :baz)

(vals {})
;;=> nil

(vals {:foo :bar})
;;=> (:bar)

(vals {:foo :bar :baz :qux})
;;=> (:bar :qux)

Clojure 1.9 agrega una sintaxis literal para representar de manera más concisa un mapa en el que las claves comparten el mismo espacio de nombres. Tenga en cuenta que el mapa en cualquier caso es idéntico (el mapa no "conoce" el espacio de nombres predeterminado), esto es simplemente una conveniencia sintáctica.

;; typical map syntax
(def p {:person/first"Darth" :person/last "Vader" :person/email "[email protected]"})

;; namespace map literal syntax
(def p #:person{:first "Darth" :last "Vader" :email "[email protected]"})


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow