Fork me on GitHub
#datomic
<
2023-12-05
>
cch121:12:30

Is it expected the java.util.Date/from is not available to Datomic Cloud queries? I know that static method is not in early-ish Java versions, but I didn’t think Datomic Cloud was running on Java that old.

Alex Miller (Clojure team)21:12:54

there is no such method - it is java.util.Date/from (was added in Java 1.8, should exist in Datomic cloud)

cch121:12:10

Sorry, that’s the method I meant to type. HEre’s the exception I see:

Execution error (ExceptionInfo) at datomic.core.require/anomaly! (require.clj:53).
Unable to load namespace for java.util.Date/from

cch121:12:49

(FWIW, this is running against Datomic Local, but I assume it’s high-fidelity with Datomic Cloud/Ion).

Alex Miller (Clojure team)21:12:58

well I will hand over to Datomic team here ... :)

thanks3 1
cch121:12:01

Minimal test case:

(let [{conn :datomic/connection} @user/sysref
      db (d/db conn)
      works-here (java.util.Date/from (Instant/now))]
  (d/q {:query '{:find [?xnow]
                 :in [$]
                 :where [[(java.util.Date/from (java.time.Instant/now)) ?xnow]]} ; not here
        :args [db]}))

dpsutton21:12:35

are quoted expressions expected to work?

cch121:12:38

I think they must be quoted.

👍 1
cch121:12:46

(generally -otherwise they expression is evaluated before submission in the query.)

cch122:12:57

Surprisingly, this works (note the immediately executed thunk):

(let [{conn :datomic/connection} @user/sysref
      db (d/db conn)
      works-here (java.util.Date/from (java.time.Instant/now))]
  (d/q {:query '{:find [?xnow]
                 :in [$]
                 :where [[(#(java.util.Date/from ^java.time.Instant (java.time.Instant/now))) ?xnow]]} 
        :args [db]}))

dpsutton22:12:22

https://docs.datomic.com/cloud/query/query-data-reference.html#built-in-functions This leads me to believe it’s a smaller set of allowable functions and not any arbitrary expression

cch122:12:23

This led me to believe that as long as the class was available on the classpath https://docs.datomic.com/cloud/query/query-data-reference.html#calling-static-methods

cch122:12:25

The fact that it works when buried inside a thunk leads me to believe that I either have the syntax wrong or there is a something wrong in the query parser.

dpsutton22:12:14

have you tried your minimal with the type hint added?

(let [{conn :datomic/connection} @user/sysref
      db (d/db conn)
      works-here (java.util.Date/from (Instant/now))]
  (d/q {:query '{:find [?xnow]
                 :in [$]
                 :where [[(java.util.Date/from ^java.util.Date (java.time.Instant/now)) ?xnow]]} ; not here
        :args [db]}))

cch122:12:53

Yes. I’ve type-hinted everything to the point where the type hints overwhelmed me.

👍 1
cch122:12:52

I got one of the type hints wrong in my example above, but correcting it does not solve the problem. Corrected version:

(let [{conn :datomic/connection} @user/sysref
      db (d/db conn)
      works-here (java.util.Date/from (java.time.Instant/now))]
  (d/q {:query '{:find [?xnow]
                 :in [$]
                 :where [[(java.util.Date/from ^java.time.Instant (java.time.Instant/now)) ?xnow]]} ; not here
        :args [db]}))
…same error.

ghadi22:12:57

no nesting allowed

cch122:12:26

That makes sense… except why is my anonymous fn allowed?

ghadi22:12:27

the docs don't mention it

cch122:12:42

I too have noticed that in some cases.

ghadi22:12:31

take out your nesting and try again

✔️ 1
cch122:12:44

Generally, I’m finding that anonymous functions solve a lot of issues with nesting. It appears as though a complex anonymous fn with typed db args works well.

ghadi22:12:50

but calling a side effect, especially clock/now is gross inside a query

ghadi22:12:01

pass that in as an ordinary arg

cch122:12:14

Yeah, this is just an example. The real work is computing a window around a db value and passing in now

cch122:12:40

(too much noise around the real issue)

ghadi22:12:51

can you describe the real work semantically? there is maybe a different way to accomplish

ghadi22:12:50

e.g. "window around db value"

cch122:12:56

Find db entities with an date attr before a cutoff that is a function of another attribute of the entity.

cch122:12:30

But, I can solve that problem in other ways (e.g. db fn).

ghadi22:12:39

a db fn is for transactions

cch122:12:49

Sorry, query fn.

cch122:12:17

The frustration is that I should be able to do it just in the query.

ghadi22:12:34

[?e :cutoff/inst ?x] [?e :date ?d] [(my-logic ?x) ?actual-cutoff] [(< ?d ?actual-cutoff)]

ghadi22:12:35

put the fn on the ion allow list

cch122:12:21

I know how to add a clojure fn … and if I have to, I’ll solve the problem that way (with deploy cycle). But why can’t it work with an inline fn?

ghadi22:12:44

the query clause is not an argument that accepts arbitrary code, even though it looks like it

cch122:12:30

That’s understandable. I hope this thread helps others that seek to find the boundary.

ghadi22:12:53

you can also do (map-or-filter (fn [ent] ...arbitrary logic) (d/index-pull ....))

ghadi22:12:08

not sure if your use-case is amenable to that

cch122:12:40

Possibly. FWIW, I’m finding that un-nesting doesn’t resolve the issue. What does seem to resolve the issue is avoiding the Class/method syntax and reverting to the (. class method) syntax.

❤️ 1
cch122:12:01

So this, surprisingly, also works:

(let [{conn :datomic/connection} @user/sysref
      db (d/db conn)
      works-here (java.util.Date/from (java.time.Instant/now))]
  (d/q {:query '{:find [?xnow]
                 :in [$]
                 :where [[(. java.util.Date from ^java.time.Instant (java.time.Instant/now)) ?xnow]]} ; not here
        :args [db]}))

🔥 1
cch122:12:32

Nested, but removing the / syntax on Date/from.

cch121:12:01

Minimal test case:

(let [{conn :datomic/connection} @user/sysref
      db (d/db conn)
      works-here (java.util.Date/from (Instant/now))]
  (d/q {:query '{:find [?xnow]
                 :in [$]
                 :where [[(java.util.Date/from (java.time.Instant/now)) ?xnow]]} ; not here
        :args [db]}))