2012-08-02 28 views
6

Về cơ bản ...Tôi có đang sử dụng nguyên tử không? sai hay có cái gì khác ....?

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

Vì vậy, có ai biết điều gì đang xảy ra không ?? Tôi đang sử dụng Eclipse Juno 4.2, plugin CounterClockwise.

Trả lời

12

Cái gọi là nguyên tử trong Clojure là thứ hoàn toàn khác với nguyên tử được gọi là nguyên tử trong Lisps khác. Trong Lisp cổ điển một nguyên tử là một giá trị duy nhất, được định nghĩa là không null hoặc không phải là ô khuyết điểm (pair):

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

Trong Clojure nguyên tử là một loại tham chiếu đồng thời. Các nguyên tử trong Clojure có thể là giá trị đơn hoặc bộ sưu tập/chuỗi, trong đó cập nhật (thay đổi trạng thái có thể thay đổi) được đảm bảo xảy ra một cách nguyên tử.

Trong Clojure có nhiều loại tham chiếu hơn danh sách khuyết điểm trong Lisp và có tất cả các loại bộ sưu tập interop Java được tính đến. Điều đó gây khó khăn cho việc xác định một kiểm tra trên các giá trị đơn.

Nếu bạn muốn, kiểm tra đơn giản nhất là xem liệu có thể đếm được thứ gì đó không. Nhìn vào (source counted), nó tham khảo clojure.lang.RT/đếm và countFrom. Ở đó, nhiều lớp/giao diện được quy định, mà tôi có trong các chức năng sau:

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

Kể từ (seq []) đánh giá để nil nó không được coi là đơn có giá trị. Tất nhiên, các đối tượng java với nhiều trường, cũng như các định nghĩa/defrecords của Clojure sẽ đăng ký như vậy, mặc dù chúng là các đối tượng tổng hợp.

3

nguyên tử? không phải là một hàm.

Bạn có thể sử dụng

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

Nếu 'nguyên tử' được không phải là một chức năng, làm thế nào đến 'danh sách?' là? Tôi có thể sử dụng 'list? 'Như một hàm và nó hoạt động, nhưng' atom?' Thì không. Tất cả điều này có vẻ rất đáng ngờ ... – Zchpyvr

+6

@Zchpyvr 'list?' Không chỉ đơn thuần là "giống như" một hàm, nhưng _is_ một hàm được triển khai một cách rõ ràng trong thư viện chuẩn và được ghi lại tại http://clojure.org/cheatsheet; 'atom? 'không phải là. –

6

tôi nghi ngờ bạn đang bối rối một clojure atom với một atom trong một cái gì đó giống như kế hoạch.

  • Đề án nguyên tử là đơn vị cơ bản.
  • Trong clojure một nguyên tử là một trong các loại tham chiếu của clojure (như ref và var) có thể được cập nhật một cách nguyên tử.

Điều này phù hợp với mô hình đồng thời của clojure.

ví dụ:

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

Bạn có thể tạo nguyên tử? chức năng như thế này:

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

Chức năng complement trả về đối diện của bất kỳ vị truyền cho nó như là đối số, vì vậy bạn có thể làm cho một atom? với nó:

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

(atom? []) ;=> false 
(atom?()) ;=> false 
(atom? {}) ;=> false 
(atom? 4) ;=> true 
Các vấn đề liên quan