This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-10-25
Channels
- # 100-days-of-code (6)
- # announcements (4)
- # aws (2)
- # beginners (151)
- # boot (1)
- # calva (1)
- # cider (19)
- # clara (47)
- # cljdoc (9)
- # cljs-dev (25)
- # clojars (18)
- # clojure (151)
- # clojure-canada (1)
- # clojure-conj (1)
- # clojure-dev (17)
- # clojure-italy (42)
- # clojure-nl (34)
- # clojure-spec (67)
- # clojure-uk (125)
- # clojurescript (163)
- # core-async (106)
- # cursive (19)
- # data-science (11)
- # datomic (9)
- # duct (2)
- # figwheel (1)
- # figwheel-main (6)
- # fulcro (97)
- # graphql (9)
- # instaparse (4)
- # jobs (6)
- # jobs-discuss (21)
- # leiningen (62)
- # mount (23)
- # off-topic (16)
- # re-frame (15)
- # reagent (16)
- # reitit (5)
- # remote-jobs (1)
- # ring-swagger (9)
- # shadow-cljs (176)
- # tools-deps (102)
- # unrepl (3)
I use =
and contanis?
. I learned it when I did not understand how clara works then never search for it.
As a newcomer it’s not super clear which functions are built-in. This is definitely an advanced user library :)
I'm believe that the only functions that Clara handles specially are the equality expressions: https://github.com/cerner/clara-rules/blob/master/src/main/clojure/clara/rules/compiler.clj#L213-L223
It still means =
too, but it can also be used for unification purposes/binding variables
Agreed with other comments that it is just = that is special when used as a top-level value in the constraint to create/join on bindings (starting with ?)
otherwise you can use arbitrary functions and they should behave the same as elsewhere
While reading the docs, it goes from straightforward to advanced very quickly. In http://www.clara-rules.org/docs/rules/, I fully understand the free-lunch-with-gizmo
because there's no ?
binding, you're matching that an item is :gizmo
, but then in the sophisticated example:
(defrule grant-discount-months
[Purchase (= ?month (get-month date))]
[DiscountMonth (= ?month month)]
=>
(insert! (->GrantDiscount :for-month ?month)))
The =
doesn't have the same meaning (in the Purchase condition) as the straightforward example, but it does in the DiscountMonth condition?it has the same meaning in that it requires equality, but clojure.core/= won’t be called
=
is unification. So, it requires the expression to be true. If there are variables in it that do not yet have a value, the variables are "assigned" such to make it true. If the variables are already assigned, it works like clojure.core/=
If there are many possible values for a variable, it can assign each value consecutively.
(*and what @mikerod is saying is true, I'm only describing the semantics, it doesn't actually work like that.)
just making sure someone may not get carried away and try to print within clojure.core/=
or something and wonder why it isn’t always called hah
[Purchase (= ?month month "JAN")]
binds the value of the field month
to ?month
, when (= month "JAN")
(via clojure.core/=
)
This page on the docs might be of interest: http://www.clara-rules.org/docs/hash_joins/
Woah secret docs
“`=` is unification” => correct. Note that this is for top-level constraints though, when nested inside a constraint that isn’t the case i.e. [A (= ?b c)] vs [A (stuff (= ?b c))]
Or more precisely on my last, that is true if you’re trying to create new bindings - it’s still unification semantically if you’re using bindings from before
> [A (= ?b c)] vs [A (stuff (= ?b c))]
Yes! This is what I ran into immediately, I wanted to use my own equality function, but I got pointed to using :test
instead.
BTW thank you all for helping me understand this!
some of the semantics around = can get weird, since it kind of plays 2 roles depending on context
Is it possible to transform the output of defquery
or would I need to do that in a wrapper function? The RHS of a defrule
is just Clojure but that doesn't seem to exist in defquery
s
@jvtrigueros defquery
has no RHS
you can create facts in rules with defrule
that do some transformations so there is less to transform once you get it from the query
but the query return val will just be the maps with the binding keys to the values they are bound to in the query
Thanks! In the query
docs, it suggests one can write a query like so:
(query session get-by-last-name :last-name “Jones”)
How would one write the defquery
for that?
(defquery get-by-last-name
[:last-name]
[?person <- Person (= last-name :last-name)])
I'm only able to create defquery
s that have ?
:
(defquery get-by-last-name
[:?last-name]
[?person <- Person (= last-name ?last-name)])
But then the query call wouldn't be using :last-name
but :?last-name