halgari / odin

An embedded extensible logic DSL for Clojure.
183 stars 11 forks source link

Fixes #12 and #13 return value if not-found in get #15

Open karlmikko opened 7 years ago

karlmikko commented 7 years ago

Added extra defmethods to replace nil value in -unify with a special gensym.

Added a step just where the reducible value is passed to with-env to replace the special gensym with nil.

These in effect wrap and un-wrap nil values in the data set.

karlmikko commented 7 years ago

The logic here is that the return for is filtered for nil through the keep in the syntax transformation so

(set (o/for-query
                  (d/query [1 2 3 nil] ?path _ ?val)
                  ?val)) 
;;=> #{1 2 3}

However if the nil bound lvar is deeper in the form it can be returned

(set (o/for-query
                  (d/query [1 2 3 nil] ?path _ ?val)
                  [?val])) 
;;=> #{[1] [2] [3] [nil]}

Which is the same behaviour as the return value of a function in the binding form

(set (o/for-query
                  (d/query [1] ?path _ ?val)
                  [((constantly nil) ?val)]))
;;=> #{[nil]}

I feel this is a happy medium for nil handling, it is at least better than throwing an exception.