meander

Zachary 2023-10-04T22:56:23.956679Z

I have a search query, something like:

(let [k :my-key]
  (m/search foo-records
    (m/scan {:my-val ?val k true})
    ?val))
Where I’m trying to pass a key in through a let binding, but it doesn’t seem to be captured. Is there a way to pass in some structure to be pattern matched?

Coby Tamayo 2023-10-07T05:37:49.318199Z

I'm not completely sure what you're asking, but I noticed you're not using k in your pattern at all

Zachary 2023-10-08T22:37:42.320069Z

Right, typo… meant for the :my-key in the body to be the k. Edited.

Coby Tamayo 2023-10-09T04:27:43.671889Z

ohhhh I see what's happening...but it threw me off for a second too. Since m/search and friends allow for arbitrary symbols in your form (like ?val is here), it's parsing k as such a symbol as well. You can unquote it with ~ to accomplish what you want though:

(let [k :my-key]
  (m/search [{:my-val 5 :my-key true :x :y}]
    (m/scan {:my-val ?val ~k true})
    ?val))
See operator https://github.com/noprompt/meander/blob/epsilon/doc/operator-overview.md#unquote.

Coby Tamayo 2023-10-09T04:46:22.712839Z

Poking at this helped me gain some intuition for how Meander works...consider that without the let binding, it doesn't throw an error to have k (not unquoted) appear in the form:

(m/search {:my-val 5 :my-key true}
  {:my-val ?val k true} ?val)
However, if you try to return k in your result, it'll throw a syntax error: Unable to resolve symbol: k in this context:
(m/search {:my-val 5 :my-key true}
  {:my-val ?val k true} [?val k])
This kinda makes sense since k is recognizably not a logic or memory var, but this is definitely a sharp edge. @noprompt is this by design? I would expect that the same logic that decides whether or something can be bound in a LHS expr should match the logic for the bindings that end up in a RHS expr as well. If there is no way to get a non-logic (/etc.) variable "out" as part of a RHS expr I would expect such a variable to get flagged as a syntax error on the LHS...but maybe I am just missing something. 🙂

Coby Tamayo 2023-10-09T04:58:12.317219Z

hmmm maybe it has to work this way in order to match on symbols?

(m/search {:my-val 5 'sym true}
  {:my-val ?val sym ?sym} [?val ?sym])