Assume I have vectors like this:
[(= :land :land) (= :good :good)]
If I do:
(every? true? [(= :land :land) (= :good :good)])
I get “true”.
If I do:
(every? true? [(= :land :land) (= :good :green)])
I get “false”.
This is fine. But I’m trying to build this vector of expressions in this function:
(defn make-query
[item f]
(loop [
k (keys f)
query
]
(if (nil? (first k))
query
(recur
(rest k)
(conj query `(= ~(get item (first k)) ~(get f (first k))))))))
This is where things get strange.
Let’s say I do this in the repl:
(def item {:type :land :status :good})
If I do:
(make-query item {:type :land :status :good})
then it seems to return:
[(clojure.core/= :land :land) (clojure.core/= :good :good)]
But if I do this:
(every? true? (make-query item {:type :land :status :good}))
I get:
false
What did I do wrong?
As background, I should explain I’m actually just trying to create something I can use as a predicate for a call to filterv. I’ve a vector full of maps, and I need a flexible way to query what is in the vector. I was actually hoping to specify the matches in a separate configuration file. But to get a flexible system, I need to get something like make-query to work.
Assume with filterv I’d use a predicate like
(fn (every? true? (make-query x f)))
I tried several things with quotes and unquote splicing but I could not get any of it to work. I was thinking I could return a list expressions and then somehow use that with the “and” macro but I could not get the syntax correct.
But let’s stick with the current question. Why doesn’t (every? true?) work on the vector returned from (make-query)?
A few more experiments at the REPL:
(first (make-query item {:type :land :status :good}))
returns:
(clojure.core/= :land :land)
but this:
(true? (first (make-query item {:type :land :status :good})))
returns:
false
but this:
(clojure.core/= :land :land)
returns:
true
UPDATE:
Hmm, okay, using “eval” seems to help:
(true? (eval (first (make-query item {:type :land :status :good}))))
returns true