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 插件。

4

5 回答 5

12

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

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

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

Clojure 中的引用类型比 Lisp 中的 cons 列表要多得多,而且还有所有 Java 互操作集合类型都需要考虑在内。这使得很难定义对单值的检查。

如果您确实愿意,最简单的检查是查看是否可以计算某些内容。看(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 将照此注册,即使它们是复合对象。

于 2012-08-02T18:05:37.520 回答
6

我怀疑您将 clojureatomatom类似计划的东西混淆了。

  • 在方案中,原子是一个基本单位。
  • 在 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)
于 2012-08-02T17:47:33.407 回答
5

原子?不是函数。

你可以使用

(def x (atom 5))
(instance? clojure.lang.Atom x)
于 2012-08-02T17:21:47.053 回答
1

你可以创建原子吗?像这样的功能:

   (defn atom? [x]
          (not (coll? x))
    )
于 2016-10-23T09:27:47.057 回答
0

complement函数返回作为参数传递给它的任何谓词的反面,因此您可以atom?使用它:

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

(atom? []) ;=> false
(atom? ()) ;=> false
(atom? {}) ;=> false
(atom? 4) ;=> true
于 2018-01-05T18:15:19.280 回答