2012-08-02 10 views
6

Zasadniczo ...Czy używam atomu? źle, czy jest coś jeszcze ...?

=> (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)

Czy ktoś wie, co się dzieje? Używam wtyczki Eclipse Juno 4.2, CounterClockwise.

Odpowiedz

12

To, co nazywane jest atomem w Clojure, jest czymś zupełnie innym niż to, co nazywamy atomem w innych Lispach. W klasycznym Lispie atom jest pojedynczą wartością, określony jako niezerowy czy komórka wad (para)

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

w Clojure atom jest oznaczenie typu współbieżności. Atomy w Clojure mogą być jednowartościowe lub kolekcje/sekwencje, gdzie gwarantowane jest przeprowadzanie aktualizacji (zmiana stanu zmiennego) atomowo.

W Clojure jest znacznie więcej typów referencji niż lista minusów w Lispie, a wszystkie typy kolekcji interopowych Java są liczone. To sprawia, że ​​trudno jest zdefiniować kontrolę pojedynczych wartości.

Jeśli chcesz, najprostszym sprawdzeniem jest sprawdzenie, czy coś można policzyć. Patrząc na (source counted), odwołuje się do clojure.lang.RT/count i countFrom. Istnieje kilka klas/interfejsy są określone, które zawarte w poniższej funkcji:

=> (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) 

Od (seq []) ocenia się nil to nie jest uważane za jedną wartość. Oczywiście obiekty java z wieloma polami, jak również Clojure defpyes/defrecords będą się rejestrować jako takie, nawet jeśli są obiektami złożonymi.

3

atom? nie jest funkcją.

Można użyć

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

Jeśli 'atom' nie jest funkcja, jak to jest 'list?' jest? Mogę użyć 'list?' Jak funkcji i działa, ale 'atom?' Nie. To wszystko wydaje się bardzo podejrzane ... – Zchpyvr

+6

@Zchpyvr 'list?' Nie jest jedynie "podobną" funkcją, ale _jest_ funkcją jawnie zaimplementowaną w standardowej bibliotece i udokumentowaną na http://clojure.org/cheatsheet; "atom?" nie jest. –

6

Podejrzewam, że mylą się Clojure atom z atom w coś podobnego schematu.

  • W schemacie atom jest podstawową jednostką.
  • W clojure atom jest jednym z typów odniesienia clojure (takich jak ref i var), które można aktualizować atomowo.

To pasuje do modelu współbieżności clojure.

np.

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

Można utworzyć atom ? funkcja tak:

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

Funkcja complement powraca przeciwieństwo dowolnego orzecznika, przekazanym mu jako argument, więc można zrobić atom? z nim:

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

(atom? []) ;=> false 
(atom?()) ;=> false 
(atom? {}) ;=> false 
(atom? 4) ;=> true 
Powiązane problemy