datomic

enn 2026-04-20T20:52:25.054689Z

Continuing my project of trying to address all of the :query-stats :unbound-var warnings in my application, I notice that Datomic warns on predicate queries like this one (example taken from the Datomic docs):

(d/q '[:find ?name
       :where [_ :artist/name ?name]
              [(<= "Q" ?name)]
              [(< ?name "R")]]
     db)
1. Is there any way to rewrite this query that will not generate a warning? 2. If not, should I interpret this warning to mean that I should be using d/datoms or d/index-range or similar here? Or would that performance be equivalent (so I can safely ignore this warning)? 3. Assuming there is an AVET index on :artist/name, does the order of the clauses impact whether the range predicate fast path documented at https://docs.datomic.com/query/query-data-reference.html#range-predicates is used? Is Datomic able to avoid binding every value of ?name even though the range predicates come after the [_ :artist/name ?name] clause?

favila 2026-04-20T21:32:32.912269Z

This warning is spurious and unavoidable. Whenever a pattern clause requires a binding it doesn't receive, you get this warning. So you're going to get this any time the first clause is a pattern clause because you gotta start somewhere.

favila 2026-04-20T21:32:57.054149Z

it's not telling you anything intelligent about index use or anything like that

favila 2026-04-20T21:35:14.530299Z

You can circumvent this warning trivially by always establishing your first binding via a function expression (e.g. [(d/datoms $ :avet :artist/name) [[_ _ ?name]]], but this can be worse than just using a data pattern clause.

favila 2026-04-20T21:37:32.908189Z

for your 3rd question, order of comparisons (also direction) doesn't matter because they will be normalized, but you should put range predicates immediately after the avet-using clause to ensure predicate pushdown

favila 2026-04-20T21:39:49.133939Z

I think if the warning is generated by the very first clause, you should just ignore it.

favila 2026-04-20T21:41:38.598859Z

The purpose of the warning is to highlight places where you may be failing to "join along".

favila 2026-04-20T21:41:55.020349Z

there's nothing to join to if you are first: you are producing the data that will be filtered/joined against

enn 2026-04-20T21:43:32.958059Z

Thanks Francis! My instinct was that this warning was not meaningful in this case, but I was not certain, so it's good to have that confirmed. > I think if the warning is generated by the very first clause, you should just ignore it. This warning did reveal some queries with unbound first clauses that did have bound inputs used later in the query, so I don't think this is safe/reliable. I'm just going to explicitly disable the linting at call sites where I know that semantically I'm just trying to get everything (or everything matching a predicate).

favila 2026-04-20T21:47:11.882839Z

Could you show me an example? I want to think about how we might suppress this warning intelligently.

favila 2026-04-20T21:47:29.362339Z

an example where it was useful would refine our thinking

enn 2026-04-20T22:11:50.305039Z

I can't share the actual code, but these were cases where the clauses were just poorly ordered. Something like this:

(def songs-by-artist
  '[:find (pull ?t pattern)
    :in $ pattern ?artist-name
    :where
    [?t :track/artists ?a]
    [?a :artist/name ?artist-name]])