Проблема заключается в том, что макросы не являются функциями - они выполняются во время компиляции и передаются с фактическим синтаксисом (прежде всего списками и символами), поэтому их нельзя применять во время выполнения к структурам данных времени выполнения. Таким образом, (apply or 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
На практике вы, вероятно, захотите some
- он останавливается, как только достигает элемента, который возвращает true, тогда как reduce
всегда пересекает весь список.
Примечание: у вас также будет такая же проблема с вашим (apply and ...)
- (every? identity ...)
будет делать то, что вы хотите.
В этом случае, однако, зачем вам вообще нужно использовать 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])))
Последнее предложение - когда вы require
clojureql.predicates заменяете clojureql.predicates
на [clojurecl.predicates :as qlp]
, вы можете использовать qlp
вместо clojureql.predicates
в остальной части файла, что делает (если мы также заменим clojureql.core
на qlc
):
(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])))
, который намного легче читать.
Для целей ClojureQL попробуйте (apply clojureql.predicates/or* ...)
и (apply clojureql.predicates/and* ...)
. where
от clojureql заменяет любые and
и or
, которые он видит, на clojureql.predicates/and*
и clojureql.or*
, поэтому выполнение этой замены самостоятельно должно работать. И and*
, и or*
являются функциями, а не макросами, поэтому проблем быть не должно.