datomic introspection stuff - survivor man driven development

6 views
Skip to first unread message

shaun gilchrist

unread,
Sep 27, 2012, 3:54:33 AM9/27/12
to church-o...@googlegroups.com
So I am working on some reflective methods for datomic - in particular I want to be able to access the various parts of the query as a map.

Datomic queries take the form of clojure vectors containing keywords and symbols/vectors e.g.

[:kw ?x ?y :kw1 [?x is ?y]]

Based on that I want to turn that into a map so I can access the parts of the query via :kw and :kw1

Here is my first stab at such a function:

(defn query-info [query]
  (let [parts (partition-by #(keyword? %) query)
        is-kw (fn [x] (keyword? (first x)))
        q-keys (map first (filter is-kw parts))
        q-vals (map #(into [] %) (filter #(not (is-kw %)) parts))]
    (zipmap q-keys q-vals)))

Just thought I would share an example of why lisp rules - being able to take someone elses DSL and write a simple introspection method on the syntax w/ minimal fuss. 

From this I now have a wrapper function for queries which returns maps instead of vectors (so you can access them via key instead of position) 

Originally I was doing: 

(defn key-query [query & args]
  (let [find-keywords (map #(keyword (subs (str %) 1)) 
                           (first (split-with #(not (keyword? %)) 
                                              (rest query))))
        result (apply q (apply conj [query] args))]
    (map #(zipmap find-keywords %) result)))

But I realized this was brittle in that it depends on the :find clause being the first part of the query. This is not a rule and just a convention thus the (query-info) function which does not depend on position but rather builds a map for each portion of the query. 

So now: 

(defn key-query [query & args]
  (let [find-keywords (map #(keyword (subs (str %) 1))
                           (:find (query-info query)))
        result (apply q (apply conj [query] args))]
    (map #(zipmap find-keywords %) result)))

Notice the trick of turning the symbols into keywords via subs. 

Anyway that is all for my survivor man driven development journal entry. -shaun
Reply all
Reply to author
Forward
0 new messages