meander 2022-09-08

hello, is there a way to match over a dynamic pattern in meander? for example:

(let [subject {:foo "bar" :baz "oi"}
        pattern {:foo "bar"}]
    (m/find subject pattern true _ false))

I tried ~pattern but that still doesn't work

I like to have a pattern that comes as an input from the user, is there a way to make it work?

Does the meander interpreter work for your use case?

I’ve used it successfully but it’s much slower than the compiled macro

what is the meander interpreter?

how can I try it?

check out meander.interpreter.epsilon

looking at it, but not sure how to use, can you give me an example snippet?

We just recently stopped using the interpreter so I don’t have an example handy…. I can dig through our git history and get you one in an hour or so

thanks 🙏

i just pulled this:

(defn meander-pattern [m match-sym]
  ['_ '... (list `mi/and m match-sym) '. '_ '...])

(defn search [m d]
  (let [s (mi/searcher (meander-pattern m '?p)
                       '?p)]
    (s (vec d))))

From what I recall, you can build the matching pattern as a flat vector and pass it to mi/searcher

The thing to understand (probably obvious from the code) is that mi/searcher returns a single arity function that returns the result of the pattern match

Is that helpful? Now that I remember, I could create a working example pretty easily

hello, I think I got it 🙂

(let [subject {:foo "bar" :baz "oi"} pattern {:foo "bar"}] ((mi/finder pattern (constantly true)) subject))

and speed still on par with my previous non-meander implementation for the simple cases 🙂

🤣 1

Yeah, I’m pretty amazed at meander 🙂

Even after using it for almost two years

this is a thing I would vote to be on Clojure core, so useful 😄

I completely agree

do you know what I need to change to make this work?

(let [subject {:foo "bar" :baz "oi"}
        pattern {:foo `(m/pred string?)}]
    ((mi/finder pattern (constantly true)) subject))

from that I got a:

Execution error (ArityException) at meander.interpreter.epsilon/eval27313$fn (epsilon.cljc:286).
Wrong number of args (0) passed to: meander.pattern-factory.epsilon/all

checking…

This returns a good result:

(let [subject {:foo "bar" :baz "oi"}
        pattern {:foo (list `m/pred string? '?var)}]
    ((mi/finder pattern (constantly true)) subject))

I think m/pred is arity two

cool, makes sense, I was assuming the other works because this is fine:

(let [subject {:foo "bar" :baz "oi"}]
    (m/find subject {:foo (m/pred string?)} true _ false))

but I guess from m/find some magic happens

That’s my guess too.

also, make sure that string? is a function and not a symbol

yup, got it :)