meander

All things about https://github.com/noprompt/meander Need help and no one responded? Feel free to ping @U5K8NTHEZ
markaddleman 2020-03-18T02:43:37.274500Z

I'm working through the meander examples at https://cljdoc.org/d/meander/epsilon/0.0.402/doc/understand-meander-s-pattern-matching-macros#rewrite I'd like to change the example a bit to return something like clojure.core's group-by. For example, I have a collection

[{:name    "entity1"
               :vals  [{:value 1} {:value 2}]}
              {:name "entity1"
               :vals [{:value 3} {:value 4} {:value 5}]}]
I'd like a meander expression to return
[{:name "entity1" :vals [1 2 3 4 5]}
The following works:
(m/rewrite [{:name    "entity1"
               :vals  [{:value 1} {:value 2}]}
              {:name "entity1"
               :vals [{:value 3} {:value 4} {:value 5}]}]
             [{:name    !name
               :vals [{:value !values} ...]} ...]
             [{:name   !name
               :value  [!values ...]} ...])
But fails to extend to multiple entity names (eg "entity2" with some vals). What's the secret sauce that I'm missing?

noprompt 2020-03-18T03:06:42.275700Z

@mark340 at the moment we typically recommend group-by πŸ™‚

noprompt 2020-03-18T03:08:48.277700Z

We are working on something which will help with reduction kinds of problems like group-by but in a robust and general way.

noprompt 2020-03-18T03:12:51.278500Z

You can do reductions with rewrite though, depending on the task, it might not be what you want.

noprompt 2020-03-18T03:16:37.279100Z

(let [es [{:name "entity1"
           :vals  [{:value 1} {:value 2}]}
          {:name"entity1"
           :vals [{:value 3} {:value 4} {:value 5}]}]]
  (me/rewrite [{} es]
    [?state []]
    ?state

    [{?name [!values ...] & ?state} [{:name ?name :vals [{:value !values} ...]} & ?rest]]
    (me/cata [{?name [!values ...] & ?state} ?rest])

    [?state [{:name ?name :vals [{:value !values} ...]} & ?rest]]
    (me/cata [{?name [!values ...] & ?state} ?rest]))
  ;; Semantically equivalent too
  (reduce
   (fn [state e]
     (me/rewrite [state e]
       [{?name [!values ...] & ?state} {:name ?name :vals [{:value !values} ...]}]
       {?name [!values ...] & ?state}

       [?state {:name ?name :vals [{:value !values} ...]}]
       {?name [!values ...] & ?state}))
   {}
   es))
;; => (let [es [{:name "entity1"
           :vals  [{:value 1} {:value 2}]}
          {:name"entity1"
           :vals [{:value 3} {:value 4} {:value 5}]}]]
  (me/rewrite [{} es]
    [?state []]
    ?state

    [{?name [!values ...] & ?state} [{:name ?name :vals [{:value !values} ...]} & ?rest]]
    (me/cata [{?name [!values ...] & ?state} ?rest])

    [?state [{:name ?name :vals [{:value !values} ...]} & ?rest]]
    (me/cata [{?name [!values ...] & ?state} ?rest]))
  ;; Semantically equivalent too
  (reduce
   (fn [state e]
     (me/rewrite [state e]
       [{?name [!values ...] & ?state} {:name ?name :vals [{:value !values} ...]}]
       {?name [!values ...] & ?state}

       [?state {:name ?name :vals [{:value !values} ...]}]
       {?name [!values ...] & ?state}))
   {}
   es))
;; =>
{"entity1" [1 2 3 4 5]}

noprompt 2020-03-18T03:23:29.280400Z

This, for example, is gross.

markaddleman 2020-03-18T04:22:24.280600Z

You know, I think you told me that before but I forgot. It seems such a natural thing to do in meander. Looking forward to zeta πŸ™‚

noprompt 2020-03-18T04:25:52.280800Z

Thanks. I want things to go more quickly but life has been more demanding than usual. πŸ˜…

πŸ˜› 1
markaddleman 2020-03-18T04:36:23.281100Z

For everyone. Stay safe; stay healthy!

noprompt 2020-03-18T05:31:25.281400Z

https://github.com/noprompt/meander/pull/120

noprompt 2020-03-18T05:32:24.282100Z

☝️ I’ll leave this open for the next day or so in case anyone wants to say something.

magnusdk 2020-03-18T10:03:11.282800Z

Hey, I’ve started using Meander more and more and it’s great! I have started getting some weird compiler exceptions however when running tests using lein kaocha --watch that occurs when reloading namespaces containing Meander code. /t

jimmy 2020-03-19T20:29:07.294900Z

This has now been fixed in β€œ0.0.408”

jimmy 2020-03-19T20:29:46.295100Z

Let us know if you run into any other issues using orchestra.

magnusdk 2020-03-19T22:44:06.297400Z

Thank you 😊

magnusdk 2020-03-18T10:03:16.282900Z

The exception is clojure.lang.Compiler$CompilerException: Syntax error macroexpanding m/rewrites at (...).

Caused by: clojure.lang.ExceptionInfo: Call to #'meander.syntax.epsilon/resolve-expander did not conform to spec:
epsilon.cljc:308
-- Spec failed --------------------
Return value
  meander.epsilon/eval13971/expander--auto--
should satisfy
  (fn
   [%]
   (or (nil? %) (sequential? %)))
-------------------------
Detected 1 error
{:clojure.spec.alpha/problems [{:path [:ret], :pred (clojure.core/fn [%] (clojure.core/or (clojure.core/nil? %) (clojure.core/sequential? %))), :val #object[meander.epsilon$eval13971$expander__9593__auto____13972 0x7abb82d6 "meander.epsilon$eval13971$expander__9593__auto____13972@7abb82d6"], :via [], :in []}], :clojure.spec.alpha/spec #object[clojure.spec.alpha$regex_spec_impl$reify__2509 0x1a0fd147 "clojure.spec.alpha$regex_spec_impl$reify__2509@1a0fd147"], :clojure.spec.alpha/value #object[meander.epsilon$eval13971$expander__9593__auto____13972 0x7abb82d6 "meander.epsilon$eval13971$expander__9593__auto____13972@7abb82d6"], :clojure.spec.alpha/ret #object[meander.epsilon$eval13971$expander__9593__auto____13972 0x7abb82d6 "meander.epsilon$eval13971$expander__9593__auto____13972@7abb82d6"], :clojure.spec.alpha/failure :instrument, :orchestra.spec.test/caller {:file "epsilon.cljc", :line 308, :var-scope meander.syntax.epsilon/expand-form}}
Has anyone else experienced a similar problem?

magnusdk 2020-03-18T13:24:36.283100Z

This is a minimal (I think) case where CompilerException is thrown

(meander/match nil
  (meander/seqable)
  nil)
It might have something to do with use of defsyntax as scan and separated causes the same issue

markaddleman 2020-03-18T15:17:14.289800Z

What are your thoughts around pluggable optimization strategies? I have a set of documents that, right now, are stored in plain Clojure sequences and yields plenty good enough performance. I have a somewhat complex meander pattern that encodes the business logic to find the right data within those documents. Over time, however, I expect the set of documents to grow perhaps to the point where sequence performance is not good enough. Much like adding an index in an RDBMS, I'd love to swap out my sequences of data for something else but not change the declarative search strategy encoding in Meander. In practice, the next performance step would be storing the data in Datascript. I can almost imagine providing Meander some hints to access the data using index seqs. Thoughts?

jimmy 2020-03-18T16:17:46.289900Z

I can definitely look into this. I'm guessing these tests are instrumenting all specs?

jimmy 2020-03-18T17:28:20.290100Z

I just tried recreating this. I instrumented every thing and tried running the code above and it ran with no issues. Do you have a project that is open with the issue? Can you share your deps? Any information for recreating would be great.

jimmy 2020-03-18T17:31:12.290300Z

We don't have any plans right now for going that route. I do think having indexes and looking up by thing is a good thing to do if you have large datasets and are looking for performance. But I'd personally recommend just making those indexes and passing them to your match. In my view, that would be the same as giving us a hint. Just give us the actual index and make your pattern match on that index.

πŸ‘ 1
magnusdk 2020-03-18T19:27:24.290700Z

Thank you for checking it out :) Yes, the tests are instrumented using https://github.com/jeaye/orchestra. Sorry for leaving out details, I’ll try my best to recreate it in a fresh, open project. I’ll get back to you

jimmy 2020-03-18T19:28:28.291Z

Orchestra would explain the difference.

jimmy 2020-03-18T19:29:11.291200Z

Hopefully have some time today to try that out and track down the issue.

magnusdk 2020-03-18T19:32:25.291400Z

I’ve recreated the issue in a new project now. I can share it on github

jimmy 2020-03-18T19:41:27.291700Z

I was able to do it with orchestra. Thanks, that was the missing piece

magnusdk 2020-03-18T19:43:12.291900Z

Awesome! I also uploaded my project here incase it’s still relevant https://github.com/magnusdk/meander-orchestra-kaocha-issue

jimmy 2020-03-18T20:02:08.292200Z

Found the issue. Should have a fix today. There is nothing actually broken going on just a bad spec.

🏎️ 1
magnusdk 2020-03-18T20:09:16.292400Z

That is fantastic! 🦜 Thank you for your time πŸ™‚ This is great

noprompt 2020-03-18T21:07:37.292700Z

Just FYI, we’re probably not going to be using spec going forward. Its been a pain for a number of users and myself.

πŸ‘ 1