datascript

2022-05-02T12:59:13.188569Z

Hey, I'm looking at rules engines, that work with datascript. I've been digging into (https://github.com/frankiesardo/minikusari) I've been using it as a really nice way to manage application complexity which is really simple to understand as it's just a function. One thing I've been thinking about is performance, there's a pretty decent thread here[0] that covers datascript performance issues which I'm slowly reading through, as well as alternatives. Are there any solutions that people are aware of that are both a reasonably performant datastore and are compatible with "rule engines"? Btw, I'm not tied to this approach, if someone can suggest something more elegant, I'd be happy to give it a go 😃... More detail in the thread, so I don't clutter up the channel! • [0]: https://clojurians.slack.com/archives/C07V8N22C/p1615872613002600

Drew Verlee 2022-05-06T01:55:00.013149Z

Let me know if you end up oaks library, I'm currently messing with it and I'm curious what other people think.

2022-05-02T12:59:34.130749Z

minikusari's implementation:

(defn r
  "Tries to match rule against db
  Returns tx-data or empty list if rule does not match"
  [{:keys [when then args]} db]
  (let [syms (for [row then el row :when (symbol? el)] el)
        results (apply d/q {:find syms :in (cons '$ (keys args)) :where when} db (vals args))]
    (for [match results tx then]
      (let [swaps (zipmap syms match)
            f (fn [x] (if (coll? x) x (get swaps x x)))]
        (walk/postwalk f tx)))))

2022-05-03T03:06:29.213909Z

Have you seen https://github.com/oakes/odoyle-rules? It's not datascript/datalog compatible, but it's similar syntax

2022-05-03T19:09:22.756999Z

Thanks @jjttjj, that's the sort of thing I was thinking about.

👍 1
2022-05-06T19:03:02.670039Z

At the moment I haven't, I've found that function I linked above is currently good enough. Once I've gotten a few more rules working and I want to see what the performance side of things looks like, then I'm planning on looking at odoyle-rules. My current plan (which maybe a terrible idea) is to benchmark it against sqlite in memory mode, my existing implementation (which it will probably beat handily). clara-rules and neanderthal. I'm aiming for a balance of performance and easy to maintain rules...

Drew Verlee 2022-05-06T20:03:44.486969Z

What is the "it" your benchmarking? The fn above?

Drew Verlee 2022-05-06T20:04:02.602419Z

I'm clueless, what would that have to do with sqlite?

2022-05-06T20:17:27.925099Z

It is the function above 😃

2022-05-06T20:23:30.028489Z

sqlite would be another way of representing data in a consistent way and processing it using rules, in a similar format to what I'm doing with :when and :then semantics above. There are clojure libs that can turn datastuctures into sql statements and then I can take my rules (a list of sql expressions evaluated in order where if they return rows, what should be run against the result) as well as the application state (current db state) and basically that would be my application. Schemaverse is an example of an application built like that [0]. odoyle and clara do something similar, though they do some additional things as they're intended to be truth maintenance systems. I'm not yet certain that I ned the extra features this provides. • [0]: https://github.com/Abstrct/Schemaverse

Drew Verlee 2022-05-06T22:20:54.473529Z

I understand, thanks!

2022-05-06T22:29:07.605349Z

You're welcome!