Hi there,
Is there a way to call Clojure functions inside queries in ClojureScript? When I run the following query using a Clojure REPL (notice the use of clojure.set/subset? in a query clause), it returns correctly:
(d/q
'[:find [?tuple ...]
:in $ ?odd-numbers
:where
[_ :tuple ?tuple]
[(set ?tuple) ?tuple-set]
[(clojure.set/subset? ?tuple-set ?odd-numbers)]]
[[1 :tuple [1 2 3]]
[2 :tuple [1 3 5]]
[3 :tuple [2 4 6]]
[4 :tuple [5 7 9]]
[5 :tuple [7 8 9]]]
#{1 3 5 7 9})
;; => [[1 3 5] [5 7 9]]
But from a ClojureScript file using a Calva REPL started with shadow-cljs, I get an error "unknown predicate 'clojure.set/subset? ...":
(d/q
'[:find [?tuple ...]
:in $ ?odd-numbers
:where
[_ :tuple ?tuple]
[(set ?tuple) ?tuple-set]
[(clojure.set/subset? ?tuple-set ?odd-numbers)]]
[[1 :tuple [1 2 3]]
[2 :tuple [1 3 5]]
[3 :tuple [2 4 6]]
[4 :tuple [5 7 9]]
[5 :tuple [7 8 9]]]
#{1 3 5 7 9})
;; => :repl/exception!
; Execution error (ExceptionInfo) at (<cljs repl>:1).
; Unknown predicate 'clojure.set/subset? in [(clojure.set/subset? ?tuple-set ?odd-numbers)]
I appreciate any help in understanding. Thanks so much!There’s no way to resolve functions at runtime in ClojureScript. So you have to pass your fn as source, like this:
(d/q '[:find ?e
:in $ ?adult
:where
[?e :age ?a]
[(?adult ?a)]]
db
#(> % 18))We hard-coded some of the most common clojure.core fns but not all of them. These can be called directly: https://github.com/tonsky/datascript/blob/e484f4ebc20caa1530aa6eaa7feb9f75b3dc0ebd/src/datascript/built_ins.cljc#L80-L99
Thank you so much!