meander

wilkerlucio 2022-09-08T20:17:02.590209Z

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))

wilkerlucio 2022-09-08T20:17:13.722499Z

I tried ~pattern but that still doesn't work

wilkerlucio 2022-09-08T20:17:29.980379Z

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

markaddleman 2022-09-08T20:32:27.158179Z

Does the meander interpreter work for your use case?

markaddleman 2022-09-08T20:32:50.244129Z

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

wilkerlucio 2022-09-08T20:39:19.072699Z

what is the meander interpreter?

wilkerlucio 2022-09-08T20:39:35.126489Z

how can I try it?

markaddleman 2022-09-08T20:49:51.246259Z

check out meander.interpreter.epsilon

wilkerlucio 2022-09-08T20:50:37.504049Z

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

markaddleman 2022-09-08T20:51:31.958559Z

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

wilkerlucio 2022-09-08T20:52:03.690019Z

thanks 🙏

markaddleman 2022-09-08T21:02:45.080989Z

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))))

markaddleman 2022-09-08T21:03:19.281639Z

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

markaddleman 2022-09-08T21:26:24.613689Z

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

markaddleman 2022-09-08T21:34:40.034009Z

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

wilkerlucio 2022-09-08T22:37:25.558669Z

hello, I think I got it 🙂

wilkerlucio 2022-09-08T22:37:25.995409Z

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

wilkerlucio 2022-09-08T22:39:08.491209Z

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

🤣 1
markaddleman 2022-09-08T22:39:33.835599Z

Yeah, I’m pretty amazed at meander 🙂

markaddleman 2022-09-08T22:39:45.177069Z

Even after using it for almost two years

wilkerlucio 2022-09-08T22:40:01.231909Z

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

markaddleman 2022-09-08T22:40:17.335329Z

I completely agree

wilkerlucio 2022-09-08T22:41:33.987049Z

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

wilkerlucio 2022-09-08T22:41:35.105069Z

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

wilkerlucio 2022-09-08T22:41:50.120149Z

from that I got a:

wilkerlucio 2022-09-08T22:41:51.612499Z

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

markaddleman 2022-09-08T22:42:10.379759Z

checking…

markaddleman 2022-09-08T22:46:26.434339Z

This returns a good result:

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

markaddleman 2022-09-08T22:46:54.902579Z

I think m/pred is arity two

wilkerlucio 2022-09-08T22:48:21.286539Z

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))

wilkerlucio 2022-09-08T22:48:29.467369Z

but I guess from m/find some magic happens

markaddleman 2022-09-08T22:48:38.819479Z

That’s my guess too.

markaddleman 2022-09-08T22:49:07.524859Z

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

wilkerlucio 2022-09-08T22:49:16.811309Z

yup, got it :)