2012-08-02 9 views
6

Básicamente ...¿Estoy usando átomo? mal o hay algo más ....?

=> (atom? 5)

CompilerException java.lang.RuntimeException: Unable to resolve symbol: atom? in this context, compiling:(NO_SOURCE_PATH:1)

=> (atom? /a)

RuntimeException Invalid token: /a clojure.lang.Util.runtimeException (Util.java:156) RuntimeException Unmatched delimiter:) clojure.lang.Util.runtimeException (Util.java:156)

=> (atom? "hello world")

CompilerException java.lang.RuntimeException: Unable to resolve symbol: atom? in this context, compiling:(NO_SOURCE_PATH:1)

¿Alguien sabe lo que está pasando? Estoy usando Eclipse Juno 4.2, el complemento CounterClockwise.

Respuesta

12

lo que se llama un átomo en Clojure es algo completamente diferente a lo que se llama un átomo en otros Lisps. En el clásico Lisp un átomo es un único valor, que se define como siendo no nulo o no una célula contras (par):

(define (atom? x) 
    (not (or (pair? x) 
      (null? x)))) 

En Clojure un átomo es un tipo de referencia de concurrencia. Los átomos en Clojure pueden ser de un solo valor o colecciones/secuencias, donde la actualización (cambio de estado mutable) se garantiza que ocurrirá atómicamente.

En Clojure hay muchos más tipos de referencia que la lista de contraseñas en Lisp, y hay todos los tipos de colección de interoperabilidad de Java a tener en cuenta. Eso hace que sea difícil definir una verificación en valores individuales.

Si lo desea, la comprobación más simple es ver si se puede contar algo. Mirando (source counted), hace referencia a clojure.lang.RT/count y countFrom. Allí, varias clases/interfaces se especifican, que he incluido en la función siguiente:

=> (defn single-valued? 
    [x] 
    (not (or (nil? x) 
       (.. x getClass isArray) 
       (some #(instance? % x) [clojure.lang.Counted 
             clojure.lang.IPersistentCollection 
             java.util.Collection 
             java.util.Map])))) 

=> (map single-valued? [1 "foo" \a 'x true not nil]) 
(true true true true true true false) 

=> (map single-valued? ['(1 2 3 4) 
         [1 2 3 4] 
         {:a 1 :b 2} 
         #{1 2 3 4} 
         (seq [1 2 3 4]) 
         (seq {:a 1 :b 2}) 
         (seq "foo") 
         (int-array [1 2 3 4]) 
         (seq [])]) 
(false false false false false false false false false) 

Desde (seq []) evalúa a nil no se considera de valor único. Por supuesto, los objetos java con múltiples campos, así como los deftypes/defrecords de Clojure se registrarán como tales, aunque sean objetos compuestos.

3

atom? no es una función.

Usted podría utilizar

(def x (atom 5)) 
(instance? clojure.lang.Atom x) 
+0

Si 'átomo de' no es una función, ¿por qué 'lista?' es? Puedo usar 'list?' Como una función y funciona, pero 'atom?' No. Todo esto parece muy sospechoso ... – Zchpyvr

+6

@Zchpyvr 'list?' No es simplemente "como" una función, sino que _es_ una función explícitamente implementada en la biblioteca estándar y documentada en http://clojure.org/cheatsheet; 'átomo?' no lo es. –

6

Sospecho que está confundiendo un clojure atom con un atom en algo así como esquema.

  • En esquema, un átomo es una unidad fundamental.
  • En clojure, un átomo es uno de los tipos de referencia de clojure (como ref y var) que se puede actualizar atómicamente.

Esto encaja muy bien con el modelo de simultaneidad de clojure.

p. Ej.

user> (def a (atom '(1 2 3)]); create an atom with value (1 2 3) 
user> @a ; look up (deference) the atoms value 
(1 2 3) 
user> (swap! a (fn [v] (map inc v))) ; add 1 to each element, v is the 
            ; old value of the atom. other threads will 
            ; see the three values in a change atomically 
user> @a 
(2 3 4) 
user> (reset! a '(5 10 15)) 
user> @a 
(5 10 15) 
1

Puede crear atom? función como esta:

(defn atom? [x] 
      (not (coll? x)) 
    ) 
0

La función complement devuelve el contrario de cualquier predicado que se le pasa como argumento, por lo que se puede hacer una atom? con ella:?

(defn atom? 
    [x] 
    ((complement coll?) x)) 

(atom? []) ;=> false 
(atom?()) ;=> false 
(atom? {}) ;=> false 
(atom? 4) ;=> true 
Cuestiones relacionadas