【问题标题】:Unexpected behaviour from clojure.java.api.Clojure来自 clojure.java.api.Clojure 的意外行为
【发布时间】:2015-02-13 10:31:25
【问题描述】:

我一直在试验 Clojure 1.6.0 中引入的clojure.java.api,因为我想将一些 Clojure 功能导入到我的 java 项目中。不幸的是,当我从 Java 调用条件函数 andor 时,它的行为与我预期的不同。

IFn and = Clojure.var("clojure.core", "and");
IFn or = Clojure.var("clojure.core", "or");

-- equivalent to (and true false) in clojure
and.invoke(true,false); --> returns true rather than false???   

-- equivalent to (or true false) in clojure
or.invoke(true,false); --> returns null rather than true???

-- equivalent to (and true true) in clojure
and.invoke(true,true); --> returns true as expected

-- equivalent to (or true true) in clojure    
or.invoke(true,true); --> returns null rather than true???

我不敢相信这是一个错误,所以我怀疑我遗漏了一些与 API 相关的相当基本的东西。不管是什么原因,这让我很困惑。如果有人能提供解释,我将不胜感激。

谢谢,

马特。

【问题讨论】:

    标签: java api clojure conditional


    【解决方案1】:

    andor 是宏,它们的评估规则有些不同。例如,在 Clojure REPL 上,尝试评估 and 会抛出 CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/and, compiling:(NO_SOURCE_PATH:0:0)

    虽然应该有一种方法可以通过clojure.java.api.Clojure 使用它们,但我现在还没有弄清楚,因为需要编译宏才能工作。

    我能想到的下一个最佳选择是使用eval,但我不确定这是您想要做的事情。另一方面,既然存在旧的&&/|| Java 运算符,为什么还要使用and/or

    【讨论】:

      【解决方案2】:

      andor 是宏,而不是函数。他们期望有两种或多种形式(我认为是符号的 clojure.lang.IPersistentList 或嵌套的 IPersistentLists),它们会扩展为 let*if 的组合。

      (clojure.walk/macroexpand-all '(and true false))
      ;returns:
      (let* [and__3941__auto__ true] 
            (if and__3941__auto__ 
              false
              and__3941__auto__))
      

      您最好制作一个代表您使用andor 的clojure fn。例如,将它们接管一个集合:

      (defn reduce-and [values]
        (reduce #(and %1 %2) values))
      (defn reduce-or [values]
        (reduce #(or %1 %2) values))
      

      【讨论】:

      • 考虑到 reduce-andreduce-or 失去了原始 orand 的短路语义,这是您有时所依赖的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-13
      • 2021-08-28
      • 2020-12-05
      • 1970-01-01
      相关资源
      最近更新 更多