datahike

https://datahike.io/, Join the conversation at https://discord.com/invite/kEBzMvb, history for this channel is available at https://clojurians.zulipchat.com/#narrow/stream/180378-slack-archive/topic/datahike
Casey 2021-02-25T16:41:22.028900Z

I'm rather new to datahike/datomic/datascript, and I'm solo here, so my learning process consists mostly of reading the datomic docs and searching open source code on github/SO Sometimes I come across code that doesn't seem to work in datahike, and I don't know why. Here's an example:

(def rules
    '[[(owns? ?uid ?e)
       [?e :auth/owner ?user]
       [?user :account/id ?uid]]
      [(owns? ?uid ?e)
       [?e ?ref-attr ?r]
       (owns? ?uid ?r)]])

  ;; Does not work
  ;; Unknown predicate 'owns? in [(owns? ?account-id ?e)]
  ;; {:error :query/where, :form [(owns? ?account-id ?e)], :var owns?}
  (d/q '[:find [?e ...]
         :in $ ?account-id %
         :where
         [?e :form/id ?v]
         [(owns? ?account-id ?e)]]
       @conn account-id rules)

  ;; Works
  (d/q '[:find [?e ...]
         :in $ ?account-id %
         :where
         [?e :form/id ?v]
         (owns? ?account-id ?e)] ;; <--- change here
       @conn account-id rules)
Why does removing the (owns?... from the vector make it work? I got the broken version https://www.slideshare.net/lucascavalcantisantos/exploring-four-datomic-superpowers (slide 56). Is this a datahike/datomic difference? Has syntax changed since 2014? Did I miss something?

kkuehne 2021-02-26T14:29:41.029700Z

Hey @ramblurr, let me check this myself and get back to you. So the query works with Datomic right?

Casey 2021-02-26T14:30:54.030Z

I only ran the code above with datahike. I pulled the code from the linked presentation where nubank was using datomic. Presumably it works in datomic, but I can't test it. I suppose it's possible they typoed in their slides, but I've seen other examples of [(rule ...)] in the wild

kkuehne 2021-02-26T15:00:50.030400Z

Ok, where does the owns? function come from?

kkuehne 2021-02-26T15:05:33.030600Z

You can use some built-in functions inside the rules that are defined https://github.com/replikativ/datahike/blob/development/src/datahike/query.cljc#L234. Alternatively you may use Java methods like .matches in Regexes as resolved in https://github.com/replikativ/datahike/blob/development/src/datahike/query.cljc#L572.

Casey 2021-02-26T15:56:57.031Z

owns? is not a function, it is a rule (see https://docs.datomic.com/on-prem/query/query.html#rules)

Casey 2021-02-26T15:58:25.031200Z

(def rules
    '[[(owns? ?uid ?e)
       [?e :auth/owner ?user]
       [?user :account/id ?uid]]
That is the "declaration" of the (owns?...) rule.

kkuehne 2021-02-26T17:04:44.031600Z

Thanks, now I understand your problem. Yes Datahike’s rules are used only without the vector, that’s how it resolves it. Inside the clause it would be treated as a predicate. In Datomic it is the same as shown in “Day of Datomic” https://github.com/Datomic/day-of-datomic/blob/master/tutorial/time-rules.clj#L50.

pithyless 2021-02-26T17:56:11.032300Z

@ramblurr I think it's just a typo in the slides. Both Datomic and DataScript differentiate rules (rule ...) from predicates [(pred? ...)] by that wrapped vector. See how the definition of a rule differs from the usage in a where clause in these examples: https://docs.datomic.com/cloud/query/query-data-reference.html#rules And you can even see it in the DataScript tests here: https://github.com/tonsky/datascript/blob/master/test/datascript/test/query_rules.cljc#L25-L26

Casey 2021-02-26T19:35:22.032700Z

Ok brilliant, that settles that. Thanks folks. One challenging thing with datomic/datahike/datascript is the web isn't full of examples and articles. Thanks for those two links, i hadn't found that datomic docs page. It shows the syntax clearly.

pithyless 2021-02-26T21:56:19.033Z

@ramblurr if you haven't seen it, http://www.learndatalogtoday.org/ is also a good source of datalog examples

Josh 2021-02-26T22:03:32.033200Z

@ramblurr in the slides, they are using map syntax for defining the query, it’s not a typo. Can’t find great docs on map vs vector queries but it is mentioned here https://docs.datomic.com/on-prem/clojure/index.html#datomic.api/q Note the use of {} not [] below to define the query

Casey 2021-02-27T07:41:49.033600Z

Ah that explains then why the rule is in a vector. There needs to be a pair so the value of the :where key is wrapped in a vector, other where clausee would presumably go inside that vector (in their own vector)