Clojureql-无法获取宏的值(clojure)

Clojureql-无法获取宏的值(clojure),clojure,clojureql,Clojure,Clojureql,我需要生成以下内容: (clojureql.core/join (clojureql.core/table db :tableA) (clojureql.core/table db :tableA) (clojureql.core/where (apply and (= :tableA.id :tableB.id) [(apply or [(clojureql.predicates/in :tableA.id [1 2])

我需要生成以下内容:

(clojureql.core/join (clojureql.core/table db :tableA) (clojureql.core/table db :tableA)
     (clojureql.core/where (apply and (= :tableA.id :tableB.id)
                      [(apply or [(clojureql.predicates/in :tableA.id [1 2])
                                  (clojureql.predicates/in :tableA.id [3 4])])])))
但是apply或form需要从另一个函数或宏传递。我的意思是:

(clojureql.core/join (clojureql.core/table db :tableA) (clojureql.core/table db :tableA)
     (clojureql.core/where (apply and (= :tableA.id :tableB.id)
                      [(my-or-f)])))
其中,该功能是:

(defn my-or-f []
    (apply or [(clojureql.predicates/in :tableA.id [1 2])
         (clojureql.predicates/in :tableA.id [3 4])]))
但是,此函数引发此异常:

#<CompilerException java.lang.Exception: Can't take value of a macro: #'clojure.core/or (NO_SOURCE_FILE:2)>
有没有其他方法可以使用应用程序或


谢谢。

如果您给出的或已知的参数数量,这可能是最简单的解决方案:

(apply #(or %1 %2) [nil 10]) ; => 10

问题在于宏不是函数——它们在编译时运行,主要是传递实际的语法列表和符号,因此不能在运行时将它们应用于运行时数据结构。因此,apply或my list会抛出一个错误。您有几个选择:

(def my-list (list false false 4 false 5))

(some identity my-list) -- returns 4
(reduce #(or %1 %2) my-list) -- returns 4
实际上,您可能需要一些—它在到达返回true的元素时立即停止,而reduce总是遍历整个列表

注意:您的申请和…-每一个身份我会做你想做的

但是,在这种情况下,为什么需要使用apply呢?这应该同样有效:

(clojureql.core/join (clojureql.core/table db :tableA) (clojureql.core/table db :tableA)
                     (clojureql.core/where (and (= :tableA.id :tableB.id)
                                                (my-or-f))))

(defn my-or-f []
  (or (clojureql.predicates/in :tableA.id [1 2])
      (clojureql.predicates/in :tableA.id [3 4])))
最后一个建议-当您需要clojureql.predicates时,如果您将clojureql.predicates替换为[clojurecl.predicates:as qlp],您可以在文件的其余部分使用qlp代替clojureql.predicates,如果我们也将clojureql.core替换为qlc,则会出现上述情况:

这更容易阅读


为了实现ClojureQL,请尝试应用ClojureQL.predicates/或*。。。并应用clojureql.predicates/和*。。。。clojureql的where用clojureql.predicates/and*和clojureql.or*替换了它所看到的任何and和or,所以自己进行替换应该是可行的。and*和or*都是函数,而不是宏,因此不应该有任何问题。

Retief,我已经尝试了您的建议,但是这不适用于clojureql库。下面是它生成的sql:SELECT tableA.*,tableA.*FROM tableA JOIN tableA ON tableA.id=tableB.id和tableA.id IN 1,2,但我需要从第一个工作示例生成的sql是:SELECT tableA.*,tableA.*从tableA连接tableA ON tableA.id=tableB.id和tableA.id(在1,2中)或tableA.id(在3,4中)问题在于clojureQL/where是一个宏,它遍历您传递的源树,查找数学和OR。在正常环境中,我的代码可以正常工作,但这不适用于clojureQL。可能有一个解决方法,但不幸的是,我实际上没有使用clojureQL,所以我不知道它。有一件事可能会奏效,那就是接受我最后的建议,不使用列表操作,将my-or-f设置为宏。@RonP检查我的编辑-我通过检查clojureql源代码找到了信息
(clojureql.core/join (clojureql.core/table db :tableA) (clojureql.core/table db :tableA)
                     (clojureql.core/where (and (= :tableA.id :tableB.id)
                                                (my-or-f))))

(defn my-or-f []
  (or (clojureql.predicates/in :tableA.id [1 2])
      (clojureql.predicates/in :tableA.id [3 4])))
(qlc/join (qlc/table db :tableA) (qlc/table db :tableA)
          (qlc/where (and (= :tableA.id :tableB.id)
                          (my-or-f))))

(defn my-or-f []
  (or (qlp/in :tableA.id [1 2])
      (qlp/in :tableA.id [3 4])))