要测试的单个谓词;自我评价“;Clojure中的原子

要测试的单个谓词;自我评价“;Clojure中的原子,clojure,predicate,Clojure,Predicate,在的主页上,有以下声明: 字符串、数字、字符、true、, false、nil和关键字评估为 他们自己 是否有一个单独的组合谓词来测试其中任何一个,组合string?,number?,char?,true?,false?,nil?和关键字?。我是否应该只使用(补码??也许我遗漏了什么,但是您可以使用以下方法来测试这些条件中的任何一个,如果其中一个条件为真,则返回true: (defn self-eval? [x] (or (string? x) (number? x)

在的主页上,有以下声明:

字符串、数字、字符、true、, false、nil和关键字评估为 他们自己


是否有一个单独的组合谓词来测试其中任何一个,组合
string?
number?
char?
true?
false?
nil?
关键字?
。我是否应该只使用
(补码?

也许我遗漏了什么,但是您可以使用以下方法来测试这些条件中的任何一个,如果其中一个条件为真,则返回true:

(defn self-eval?
  [x]
  (or (string? x)
      (number? x)
      (char? x)
      (keyword? x)
      (true? x)
      (false? x)
      (nil? x)))

编写一个宏来询问“给定表达式是否自行计算”是很容易的。事实上,这是一个很好的例子,说明只能使用宏来完成任务,因为它们需要同时查看已计算和未计算的参数

(defmacro selfp [a] `(= ~a (quote ~a)))
#'user/selfp
user> (selfp 1)
true
user> (selfp +)
false
user> (selfp [1 2])
true
user> (selfp '(+ 1 2 3))
false

虽然字符串、数字、字符、关键字和布尔值都是自评估的,但其他东西,如
[12]
也是自评估的,因此这通常不是一个有用的测试

另一个选项是创建使用映射的函数:

(defn myclassifier? [x]
   (let [types-I-care-about #{java.lang.Sring ...}]
      (if (types-I-care-about (type x))
          true
          false)))
另一个可能具有更好性能的选项是使用java的动态性:

(extend-type Object
  IMyClassifier
  (myclassifier? [x]
            (let [c (.getClass x)]
             (if (types-I-care-about (type c))
               (do
                 (extend-type (.getClass x)
                   IMyClassifier
                   (myclassifier? [x] true))
                 true)
               false))))

其中types-I-care-about是一组您关心的类型。

好问题。我的想法是,在主Clojure API中还没有一个谓词可以这样做。虽然在第三方API中可能有,但是评估它并检查它是否等于它本身怎么样:-)@mikera:请看Arthur Ulfeldt的答案。这正是我所做的。我想知道是否有一个谓词可以同时测试所有谓词。FWIW这与
(defn self eval?[x](一些#(%x)[string?number?char?keyword?true?false?nil?]一样重复性较小
@amalloy感谢您提供了较短的版本。在Clojure中使用
some
是一个有趣的习惯用法;很高兴在这里再次使用它,不过对于绝对初学者,我认为
版本可能更容易理解。
(def j'j)(selfp j)
使符号看起来好像是自我评估的,但它们当然不是。我想你最好还是用semperos的答案。@amalloy:在我的例子中,我在宏中使用测试来决定是否需要引用某个值。如果该值评估为自身,那么它是符号还是其他东西真的无关紧要。我我想我可以像写的那样使用
selfp
。@拉尔夫,这是非常错误的!
selfp
测试某些内容在当前上下文中是否计算为自身。宏上下文几乎总是不同于扩展上下文;而且因为
selfp
是一个宏,所以它只对文本起作用(您已经知道是否要引用了!)。例如,请参阅:此宏正确引用了
stuff
,但同时错误地引用了
:test
item
。(事实上,它总是引用除文字符号
item
之外的任何内容)@amalloy:谢谢你的例子。这解释了为什么我的宏不起作用。我写了一个宏,它接受一组JComponents和GridBagConstraints,并将它们构建到GridBagLayout中。我的宏为GBC设置了一些默认值,包括
(插图5)
。我正在尝试引用默认值中的值,而不是组件规范中的“重写”值。我可以让它工作,但前提是我在重写中写出
(java.awt.Insets.2)
。我试图自动引用它,但现在,我将保持原样。我将尝试提出一个精简的示例。