2012-08-02 57 views
6

基本上...我在用原子吗?错误还是有其他的东西....?

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

那么有谁知道发生了什么? 我正在使用Eclipse Juno 4.2,CounterClockwise插件。

回答

12

Clojure中所谓的原子与其他Lisp中的原子完全不同。在经典Lisp中的原子是一个单一的值,定义为不为空或不cons单元(一对):

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

在Clojure中的原子是一种并发引用类型。 Clojure中的原子既可以是单值的,也可以是集合/序列,其中更新(可变状态变化)保证以原子方式发生。

在Clojure中,引用类型远多于Lisp中的缺点列表,并且还有所有的Java interop集合类型都要考虑。这使得很难定义对单值的检查。

如果你确实想要,最简单的检查是看看是否有东西可以计算。查看(source counted),它引用了clojure.lang.RT/count和countFrom。在那里,几个类/接口指定的,这是我包括在以下的功能:

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

由于(seq [])评估为nil它不被认为是单值。当然,包含多个字段的java对象,以及Clojure deftypes/defrecords也会这样注册,即使它们是复合对象。

3

atom?不是一个功能。

你可以使用

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

如果'原子'是不是一个函数,'list?'怎么样?我可以使用'list?'就像一个函数,它可以工作,但'atom?'不会。这似乎是非常可疑的...... – Zchpyvr 2012-08-02 17:36:14

+6

@Zpypyvr列表?'不仅仅是“喜欢”一个函数,而是_is_一个明确在标准库中实现的函数,并记录在http://clojure.org/cheatsheet; '原子?'不是。 – 2012-08-02 17:37:42

6

我怀疑你是在类似方案混淆一个Clojure的​​有​​。

  • 在方案中,原子是一个基本单位。
  • 在clojure中,原子是clojure的引用类型之一(如ref和var),可以自动更新。

这很适合clojure的并发模型。

例如

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

您可以创建原子?功能是这样的:

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

complement函数返回传递给它的参数中的任何谓语的对面,所以你可以做一个atom?吧?

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

(atom? []) ;=> false 
(atom?()) ;=> false 
(atom? {}) ;=> false 
(atom? 4) ;=> true 
相关问题