I was looking at updating Datomic Pro 1.0.6610 to a newer version, the first thing I notice is the https://docs.datomic.com/operation/aws.html have a deprecation about the CloudFormation related commands. Can I still use create-cf-template ? I see it still exists in bin/datomic of datomic-pro-1.0.7394.
Well 🤔 looks like it's working
Is there a value that sorts higher than any value for all types, suitable for passing to d/index-range as end-tuple component?
• e.g. (sort [true false nil]) => [nil false true]
• so want something like infinity such that (sort [true false infinity]) => [false true infinity]
• because (sort [true false :more]) => throws Boolean cannot be cast to clojure.lang.Keyword.
Reason being d/index-range's end-tuple is exclusive, so I'm trying to figure out which value I can pass an end-tuple component that will include both true & false in :db.type/boolean tuple components.
Is the performance of take-while equivalent to specifying an end-tuple value?
yes
well, more precisely, depends on the contents of the take-while
there's no significant inherent overhead to consuming the result via take-while and terminating vs index-range doing the same internally
there likely is one, but it would be an accident of implementation
You should make a take-while with the appropriate <= condition
alternatively you can increment the tuple slot to the left by one, leave the trailing items nil
does datomic pro print and read queries during datomic.api/q, maybe as part of its query cache? we’ve changed the #inst reader in our project to return java.time.Instant and now a java.util.Date we pass to a query comes out as a java.time.Instant . Is that expected & documented somewhere?
whoa. I would NOT do that @mkvlr
The reason is that I would consider this to be entirely in "Undefined Behavior" territory. Maybe what we could do in this conversation is start back at the the question "Why are you trying to use j.t.Instant for #inst in your project?"
> "Why are you trying to use j.t.Instant for #inst in your project?"
My takeaway from https://widdindustries.com/blog/what-is-inst.html was that that's acceptable usage for data readers like #inst
Function expressions in queries are compiled with eval. In your case it would be evaluating something like (clojure.core/fn [?exit] (java.util.Date/.before ?exit
But for reasons I don't know, clojure eval invokes the reader on the date object:
(let [v (binding [*data-readers* (assoc *data-readers* 'inst (fn [cs] (prn [(class cs) cs]) (java.util.Date/.toInstant (clojure.instant/read-instant-date cs))))]
(eval `(fn [] ~(java.util.Date.))))]
(class (v)))
[java.lang.String "2025-10-20T15:41:46.665-00:00"]
=> java.time.Instantnote there's no datomic in the code above
this is just what clojure eval does
If you don't try to put a date constant into your query, you should be fine; supply the correct date object as an :in parameter
Just to be extra clear that eval definitely got a date object, not a string:
(let [d (java.util.Date.)
expr `(fn [] ~d)
f (binding [*data-readers* (assoc *data-readers* 'inst (fn [cs] (prn [(class cs) cs]) (java.util.Date/.toInstant (clojure.instant/read-instant-date cs))))]
(eval expr))
v (f)]
{:into-eval [(class (last expr)) (last expr)]
:out-eval [(class v) v]})
[java.lang.String "2025-10-20T15:53:34.704-00:00"]
=>
{:into-eval [java.util.Date #inst "2025-10-20T15:53:34.704-00:00"],
:out-eval [java.time.Instant #object [java.time.Instant 0x26cdb25d "2025-10-20T15:53:34.704Z"]]}@favila oh wow, I had no idea eval does that, thanks for the explanation!
@joe.lane we’re trying to avoid java.util.Date on our project. I had the impression also from https://clojure.org/reference/reader#_built_in_tagged_literals that #inst is just one implementation and changing it is allowed, since there’s even an alternative implementation in clojure.core.
@favila it’s the quoting that brings in the pr / read roundtrip, which makes sense I guess:
(let [date (java.util.Date.)]
(binding [*data-readers* (assoc *data-readers* 'inst (fn [cs] (java.util.Date/.toInstant (clojure.instant/read-instant-date cs))))]
{:plain (let [expr date]
[(type (eval expr)) expr])
:quoted (let [expr (list 'quote date)]
[(type (eval expr)) expr])}))
;; => {:plain [java.util.Date #inst "2025-10-20T23:14:51.461-00:00"], :quoted [java.time.Instant (quote #inst "2025-10-20T23:14:51.461-00:00")]}It's not the quoting, it's just being a subexpression
huh, you’re right
(let [date (java.util.Date.)]
(binding [*data-readers* (assoc *data-readers* 'inst (fn [cs] (java.util.Date/.toInstant (clojure.instant/read-instant-date cs))))]
{:plain (let [expr date]
[(type (eval expr)) expr])
:in-vector (let [expr [date]]
[(type (first (eval expr))) expr])}))
;; => {:plain [java.util.Date #inst "2025-10-20T23:59:40.769-00:00"], :in-vector [java.time.Instant [#inst "2025-10-20T23:59:40.769-00:00"]]}(let [expr (list 'clojure.core/vector (java.util.Date.))]
(-> (binding [*data-readers* dr-instant]
(eval expr))
first
class))
=> java.time.Instant
(let [expr (list 'do (java.util.Date.))]
(-> (binding [*data-readers* dr-instant]
(eval expr))
class))
=> java.util.Date
(let [expr (java.util.Date.)]
(-> (binding [*data-readers* dr-instant]
(eval expr))
class))
=> java.util.Datenote the do magic
again, no idea why it's like this, or even how
I was thinking to rebind the #inst reader locally in our datomic wrapper, but that also didn’t help. Is the eval delayed?
I think I’ll throw instead when passing inst? constants as part of the query since it’s discouraged anyway and defeats the caching etc
Here’s a gist showing what I mean https://gist.github.com/mk/e1e2955dc4c892ca7214185072047bda
also created an ask for this as I thought something more permanent than slack might be better as a reference : https://ask.datomic.com/index.php/1867/why-does-changing-the-inst-reader-make-my-query-fail