This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
@mikerod hm, ok. Idempotency shouldn't be an issue, good hint though. Gonna try that, although I am not 100% clear on how you mean that. In my use case, there would be rules that produce a [Linked a b] fact which would call something like core.async/pipe on a and b, only it returns something that can be called or closed when the respective Linked fact goes away in order to sever the connection again. How would I address that using :not rules?
@mrchance an alternative that comes to mind is to hook into Clara’s listeners to try to watch for the particular retraction you are interested in. However, I’d probably say it is best if that isn’t necessary.
I hate to suggest things like
insert-unconditional! but I see an approach with that at least…
(defrule makes-chan [?a <- A] [?b <- B] => (let [chan (somehow-make it)] ;; Not sure what you do with `chan` here (r/insert! (->LogicalThing ?a ?b)) (r/insert-unconditional! (->OpenedChan chan)))) (defrule closes-chan [:not [LogicalThing]] [?oc <- OpenedChan (= ?chan chan)] => (r/retract! ?oc) (close-the ?chan))
I think it just gets sort of dirty when you are managing your own unconditional facts and retracts - typically a pattern to avoid
not sure how prevalent this would be for you though in terms of managing it. also, not positive my solution is really a solution to the issue at all
even when looking at this though, I think it is perhaps opaque which retraction you’d want to listen to
(retract-facts! [listener facts]) &
(retract-facts-logical! [listener node token facts]) would have the info
retract-facts! I believe is retracts from the RHS and
retract-facts-logical! is retracts from truth maintenance
I think there is some big potential here, like a completely reactive description of stateful systems, something that's always awful when it moves past what e.g. component can handle
yeah, it isn’t actually documented on
mk-session, not sure why. I don’t think those ns’s are really called “experimental” around this at this point
the only thing I’m concerned about is if you do not impl all the functions of the protocol
> I think there is some big potential here, like a completely reactive description of stateful systems, something that’s always awful when it moves past what e.g. component can handle That is cool though
I knew they were doing interesting things in using Clara for app state mgmt (may be saying that wrong)
Several people have had use cases that sounded like what they were looking for was the ability to get the changes in query results relative to an earlier state, and it sounds like that sort of functionality might be what you’re looking for as well @mrchance . That could be done with some wrappers in your code around the session along the lines of “Query the session, store the results, insert/retract facts, fire the rules, then query again and diff the results”. It could be done as a Clara listener too by tracking on the listening calls in QueryNode: https://github.com/cerner/clara-rules/blob/0.15.2/src/main/clojure/clara/rules/engine.cljc#L430
It is functionality that I think would be useful for Clara itself to provide at some point, a listener to do that would probably get into Clara’s internal impl details somewhat e.g. “is this node a QueryNode?” logic. Wouldn’t matter if it was part of Clara and tested there though.
@wparker True, that's another way to look at it. This might work too. Your answer also makes me wonder if Datascript would be the better choice for this usecase though, since there you get the transaction logs anyway
I haven’t had occasion to use DataScript, but it also seems like something that could be useful for a use-case like what you describe @mrchance . I suspect much depends on what the simplest way to model the logic you have in mind is and what performance characteristics you’re looking for.