This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-01-13
Channels
- # beginners (99)
- # boot (2)
- # boot-dev (4)
- # chestnut (2)
- # cider (75)
- # clara (43)
- # cljs-dev (1)
- # cljsjs (6)
- # cljsrn (4)
- # clojars (2)
- # clojure (76)
- # clojure-brasil (1)
- # clojure-france (1)
- # clojure-italy (2)
- # clojure-spec (30)
- # clojure-uk (4)
- # clojurescript (39)
- # core-async (1)
- # core-logic (2)
- # cursive (1)
- # data-science (7)
- # datomic (14)
- # docker (12)
- # emacs (6)
- # fulcro (69)
- # garden (4)
- # hoplon (7)
- # jobs-discuss (46)
- # leiningen (3)
- # lumo (3)
- # off-topic (12)
- # om (2)
- # parinfer (12)
- # perun (9)
- # re-frame (44)
- # reagent (6)
- # rum (1)
- # shadow-cljs (73)
- # specter (5)
- # unrepl (10)
- # vim (2)
I took a shot at forcing conditional inserts in the async handler, if only as an exercise to understand the code better. I got as far as actually getting the insert to occur, basically grabbing the *rule-context*
and making it available to the handler, and adding an overload of fire-rules
that would accept that as an extra parameter. The rule context was modified so it only contained non-empty :batched-logical-insertions
with the facts being inserted as a logical consequence of the rule triggering the async effect. clara.rules.engine/*fire-rules*
then also had an extra arity to deal with externally supplied rule context. At this point, I guessed that this approach probably wouldn't work in general, because it looks to me like the :token
in the rule context contains the fact bindings which are the logical antecedent. If any of those facts had been retracted in the session between the request and response of the async effect, I assume that clara.rules.memory/add-insertions!
would be unhappy, as the token would be inconsistent with the state of working memory. Is that correct?
Also working memory is in a mutable state. I think things could easily become inconsistent.
Makes sense.
Is there a way to force a rule to fire, even if the fact values don't change? I'm playing around with using an atom to solve this case, but of course the atom reference doesn't change when the atom is reset, only the wrapped value changes, so the rule won't fire after the first time.
@dave.dixon > Is there a way to force a rule to fire, even if the fact values don’t change? No offense intended at all but that seems off to a bad start even to me…. 😄 What are you trying to do?
Yeah, it sounds bad. I'm trying to get the rhs to evaluate when a fact refers to an atom and the atom value changes.
Interesting. Why an atom?
So I can put the response from an async request in it.
Hm ok. Have you tried calling deref on the atom in the condition
Yes. Doesn't help. In fact, it doesn't work in general for making the bindings, which seems odd.
Hm. Potentially wild things I’d try: 1. (deref a) instead of the macro if you’re not already, 2. :test expression
Have tried both. Deref doesn't help, but the reader macro works in a test and rhs.
Well I’m confused. @mikerod might be able to shine light on it
I am not sure I understand still. Been traveling today though so somewhat on and off here
I'll post it when I get home.
Does Clara support namespace aliases in Fact matching? The following throws an exception, but the long-form works:
[encounter-actions/EncounterFindingChanged ..] ;; short -- throws ex
[justice.models.core.actions.encounter.EncounterFindingChanged ..] ;; long
I hit a similar issue using a macro in a rule definition.
@mikerod I'll file an issue, I replicated it with the intro to clara example just moving the defrecords into another ns
@dadair if it’s cljs perhaps it relates to some recent issues already out there. I thought it was fixed though.
Unless you didn’t include the alias in the ns or something. Hah. If you could make like a small example where it isn’t working that’d be nice to see.
(ns abc.other)
(defrecord SupportRequest [client level])
(defrecord ClientRepresentative [name client])
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(ns abc.core
(:require [clara.rules :refer :all]
[abc.other :as other]))
(defrule is-important
"Find important support requests."
[abc.other.SupportRequest (= :high level)] ;; full path here works; change to other/SupportRequest and an exception is thrown
=>
(println "High support requested!"))
(defrule notify-client-rep
"Find the client representative and request support."
[abc.other.SupportRequest (= ?client client)]
[abc.other.ClientRepresentative (= ?client client) (= ?name name)]
=>
(println "Notify" ?name "that"
?client "has a new support request!"))
(-> (mk-session 'abc.core)
(insert (other/->ClientRepresentative "Alice" "Acme")
(other/->SupportRequest "Acme" :high))
(fire-rules))
They don’t support ns aliasing. Their builder functions do but not the type class itsel
@dave.dixon so in the one that works are there different time facts with different time values?
@alex-dixon I haven't tried multiple time facts. I think it should work correctly with upsert, though. Retracting existing fact would lead to retraction of the generated Tag facts, and the subsequent insert would generate an updated set.
I was hoping to get away from having auxiliary unconditional facts like Time
. The other version of async is structurally similar, but there the external fact is Response
, which is correlated via a rule with the original Request
. There's an additional rule that forces retract of Response
when the corresponding Request
no longer exists.
Given that both approaches require unconditional inserts, the Request
/`Response` pattern is arguably cleaner, as the atom approach requires some extra coordination outside of the rulebase to correctly update the session when the atom value changes.
I’ll definitely keep this in mind as I try to do similar things. Wish I could be more help but it gets hard for me to reason about and I find my thinking tending toward more immutable approaches which seems like the opposite of the overall approach (fewer intermediate facts/garbage). I’ll try to experiment next time I’m at a laptop
Curious, did you try a callback in the rhs and logical insert? Seem to recall that being your first approach. If so what happened? Loss of session context?