Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong function selection with input relation join #283

Closed
darkleaf opened this issue Jan 4, 2019 · 7 comments
Closed

Wrong function selection with input relation join #283

darkleaf opened this issue Jan 4, 2019 · 7 comments

Comments

@darkleaf
Copy link
Contributor

@darkleaf darkleaf commented Jan 4, 2019

Hi.
It's seems that datascript applies functions from input relations incorrectly.

Version: "0.17.1"
Clojure 1.10.0, Java 11.0.1, JVM version

Minimal example:

(let [db (-> (d/empty-db)
             (d/db-with [{:a :val
                          :b :val}]))]
  (d/q '{:find  [?a ?res]
         :in    [$ [[?a ?fn]]]
         :where [[_ ?a ?v]
                 [(?fn ?v) ?res]]}
       db [[:a (constantly :a-val)]
           [:b (constantly :b-val)]]))

Expected:

#{[:b :b-val] [:a :a-val]}

Actual:

#{[:b :a-val] [:a :a-val]}

Another example:

(let [db (-> (d/empty-db)
             (d/db-with [{:a 0
                          :b 0}]))]
  (d/q '{:find  [?a ?fn ?res]
         :in    [$ [[?a ?fn]]]
         :where [[_ ?a ?v]
                 [(?fn ?v) ?res]]}
       db [[:a inc]
           [:b dec]]))

Expected:

#{[:b #function[clojure.core/dec] -1]
  [:a #function[clojure.core/inc] 1]}

Actual:

#{[:b #function[clojure.core/dec] 1]
  [:a #function[clojure.core/inc] 1]}
@tonsky

This comment has been minimized.

Copy link
Owner

@tonsky tonsky commented Jan 4, 2019

Yeah you can’t do that. You can’t dynamically choose functions/sources

@darkleaf

This comment has been minimized.

Copy link
Contributor Author

@darkleaf darkleaf commented Jan 5, 2019

If I understand correctly datomic doesn't allow to pass functions as inputs.
So this is datascript specific feature.

Is it posible to implement dynamic function choose?
How difficult is it to do this?

@tonsky

This comment has been minimized.

Copy link
Owner

@tonsky tonsky commented Jan 6, 2019

Not difficult but might be pretty costly for situations where there’s only one functions, which is a majority of cases

@darkleaf

This comment has been minimized.

Copy link
Contributor Author

@darkleaf darkleaf commented Jan 7, 2019

Which main pattern? Is single function specified as input or it's just a rule?

(ns data ...)

(defn foo [x] false)

(let [db (-> (d/empty-db)
             (d/db-with
              [{:foo :bar}]))]
  (d/q '{:find [?e]
         :where [[?e ?a ?v]
                 [(data/foo ?v)]]}            
       db))

I want to validate my datoms with map like this:

{:ns/key string?
 :ns/key1 (fn [x] true)
 :ns2/key int?
;;...
}
@tonsky

This comment has been minimized.

Copy link
Owner

@tonsky tonsky commented Jan 7, 2019

You usually apply one fn per all datoms, not a fn per datom. In the latter case, just select what you need and apply fn yourself. Or call apply with fn as an argument

@darkleaf

This comment has been minimized.

Copy link
Contributor Author

@darkleaf darkleaf commented Jan 7, 2019

Yep, I can use index scan for this kind of validation.

@darkleaf

This comment has been minimized.

Copy link
Contributor Author

@darkleaf darkleaf commented Jan 14, 2019

Tricky workaround:

(let [db (-> (d/empty-db)
             (d/db-with [{:a 0
                          :b 0}]))]
  (d/q '{:find  [?a ?fn ?res]
         :in    [$ [[?a ?fn]]]
         :where [[_ ?a ?v]
                 [(clojure.core/apply ?fn ?v []) ?res]]}
       db [[:a inc]
           [:b dec]]))
@tonsky tonsky closed this Jan 26, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.