This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-07-07
Channels
- # announcements (1)
- # babashka (31)
- # beginners (54)
- # biff (3)
- # calva (22)
- # cider (13)
- # circleci (1)
- # clj-kondo (6)
- # cljsrn (2)
- # clojure (113)
- # clojure-europe (58)
- # clojure-mexico (5)
- # clojure-nl (3)
- # clojure-uk (7)
- # clojurescript (81)
- # cursive (20)
- # datomic (33)
- # events (3)
- # fulcro (29)
- # introduce-yourself (1)
- # meander (78)
- # off-topic (60)
- # om-next (2)
- # podcasts-discuss (1)
- # re-frame (8)
- # reagent (5)
- # reitit (20)
- # remote-jobs (1)
- # shadow-cljs (24)
- # spacemacs (10)
- # sql (8)
- # tools-deps (22)
- # xtdb (16)
A million questions I know but is there a better way to work with scalars withing a query? I am doing this at the moment for calculating a percentage - I know I could have a clojure function that does that for me but I was just wondering...
[(/ ?interesting-subsegment-count ?all-subsegment-count)
?ratio]
[(float ?ratio)
?float-ratio]
[(* 100 ?float-ratio)
?percentage]
If I don't do that I get a bunch of "Cannot cast XYZ to java.lang.Number` and similar😄 keep the questions coming! Unfortunately there's no "better" option than the two you've mentioned. There is a way to embed arbitrary Clojure in your Datalog using a custom predicate
(defn inline-clj-pred [f & args]
(apply (eval f) (vec args)))
...but I strongly discourage using it beyond prototyping(!)
https://gist.github.com/refset/a7f86c8a3ad34aea5d20eac0b5720a28Ah, yeah I was actually wondering if I could express ranges with inequalities (data like 10 :<= x :< 11
) and the use some magic for apply them in a rule 😄
The other option above probably gets close to it without eval
- I'll have to play but thank you!
Crux is able to combine range predicates cleverly so you can do [(<= 10 x)][(< x 11)]]
with separate clauses and it should be fast
beware though that the range predicates are Crux-Datalog specific, so they don't necessarily respect type boundaries, unlike how clojure.core/>
and friends behave where you can combine quite a few different types of numbers without worry. You can always specify [(clojure.core/<= 10 x)][(clojure.core/< x 11)]]
if needed though
I feel a bit dirty but here it is 😄
(defn inequalities-satisfied? [inequalities x]
(let [eval-fn (fn [inequality]
(let [[operator y] inequality
operator-sym (symbol operator)]
(eval `(~operator-sym ~x ~y))))]
(every? true? (map eval-fn inequalities))))
(inequalities-satisfied? [[:>= 14] [:<= 17]] 17) ;;=> false
Spike = playing around!For this one I am representing now classifications as
(crux/submit-tx node [[:crux.tx/put
{:crux.db/id {:measurement-name "ASW Tris"
:classification :classification/severe}
:cohesic/type :classification-range
:classification/range #{[:>= 18]}}]])
Note that range is the set of my inequalities.
Is there a way to tell Crux to leave that :classification/range
key alone and assign it to a variable "as is" without decomposing?an example query is
(crux/q
(crux/db node)
'{:find [(pull ?cs1 [*])]
:in [?input]
:where [[?cs1 :cohesic/type :classification-range]
[?cs1 :classification/range ?inequalities]
[(println ?inequalities)]
]}
17)
where I would like to see ?inequalities
as #{[:>= 18]}
but I see it as [:>= 18]
insteadreading this https://opencrux.com/reference/queries.html#_maps_and_vectors_in_data It seems I will have to create an artificial subkey for that so that the top level won't be decomposed?
that's definitely an option, you could also use the semi-official built-in get-attr
predicate like this https://github.com/juxt/crux/blob/63e99523b73478490618c99760f3e28e2e1acf33/crux-test/test/crux/query_test.clj#L1077-L1082# (except don't do the destructuring) - I think it will always return a vector with ~undefined ordering. and I can confirm that for you if you want to go down that route
no ordering should be fine - it's a really a set of inequalities what I am trying to get.
Given you asked more questions 😄 Does binding results (via :find
) currently works in Crux?
I tried the Datomic syntax but it does not seem to be working https://docs.datomic.com/cloud/query/query-data-reference.html#find-variables-example
This is especially nice for aggregation functions and scalars, for instance when you want to (count ?foo)
it's really nice to get a clean number out of the query
Crux doesn't currently support the `find-scalar`or `find-coll` parts of the edn Datalog query spec (i.e. .
and ..
), but things like aggregates (`count` and friends) should definitely work for you, see https://opencrux.com/reference/1.17.1/queries.html#find-aggregate
I think you can do some tricks to get a collection back using a subquery, but at the top level you'll always get a set back from Crux's q
as things stand today
For this one I am representing now classifications as
(crux/submit-tx node [[:crux.tx/put
{:crux.db/id {:measurement-name "ASW Tris"
:classification :classification/severe}
:cohesic/type :classification-range
:classification/range #{[:>= 18]}}]])
Note that range is the set of my inequalities.
Is there a way to tell Crux to leave that :classification/range
key alone and assign it to a variable "as is" without decomposing?reading this https://opencrux.com/reference/queries.html#_maps_and_vectors_in_data It seems I will have to create an artificial subkey for that so that the top level won't be decomposed?