meander

All things about https://github.com/noprompt/meander Need help and no one responded? Feel free to ping @U5K8NTHEZ
ikrimael 2020-07-23T06:10:17.156300Z

oops; forgot to actually paste

ikrimael 2020-07-23T06:12:11.156500Z

sigh, now I forgot the exact context which I was asking around. let me circle back after I hit it again (won't be long since it's a top 3 pattern I keep hitting)

ikrimael 2020-07-23T06:15:12.157900Z

yeah. i'm a big believer in "stop forcing devs to play compiler/computer in their heads"

ikrimael 2020-07-23T08:12:28.158Z

(m/match
 [{:type   "Operator"
   :fields [{:type "int32" :name "age" :meta [[:uiSlider 1 100] [:tooltip "MyTool"]]}
            {:type "uid_t" :name "id"  :meta [[:hidden]]}]}
  {:type   "Graph"
   :fields [{:type "vec<int32>" :name "nodes" :meta [[:hidden]]}
            {:type "graphDesc"  :name "meta"  :meta [[:hidden]]}]}]

  [[{:type !type :fields ?flds} ...]]
  (;; Can't use meander syntax to rewrite/pattern match inside of ?flds and have to resort to let destructurings
   )
  
 [[{:type !type :fields [{:type !fldtype :name !fldname :meta !meta}  ...]} ...]]
  (;; !fldtype,!fldname,!meta are no longer "grouped" together to the type they were in
   ))

ikrimael 2020-07-23T08:12:43.158200Z

so this is the problem distilled down

ikrimael 2020-07-23T08:13:50.158400Z

what I "discovered" last night is using (m/cata) to recurse down and creating a pattern match term for each "nesting level"

ikrimael 2020-07-23T08:17:14.158600Z

it's a decent compromise but i'm left wanting: - separating out to different terms erases context of which nested terms are allowed to appear where - found it harder to debug, both along user syntax errors and logic. What i'd end up doing is replace each pattern match term one by one starting from the top until i found which nesting level had an issue, then proceed from there

ikrimael 2020-07-23T08:20:03.158800Z

some mitigations to issues above: - discovered datawalk which has been a godsend and made the above process a lot less painful - since the nesting match terms are all together, it's not that bad. instead of instant grokking of the code, maybe it's 5-10 mins as one mentally reconstructs which terms are allowed to go where

ikrimael 2020-07-23T08:20:47.159Z

as a real world ex: here's the code from last night: https://gist.github.com/ikrima/0353f3f1600a639797c63b2692c63334

murtaza52 2020-07-23T09:18:38.160300Z

Given the code below -

(m/search [{:farm ""}
           {:farm "a"}
           {:farm ""}]
  (m/scan {:farm _ :as ?row})
  (assoc ?row :farm "b"))
Is there a better way to rewrite it, I am basically trying to substitute the :farm value for a given collection of hash-maps.

jimmy 2020-07-23T14:00:24.160400Z

Here are two other ways you could write this:

(m/rewrite [{:farm ""}
            {:farm "a"}
            {:farm ""}]
  [{:farm _ & !rest} ...]
  [{:farm "b" & !rest} ...])


(m/rewrites [{:farm ""}
             {:farm "a"}
             {:farm ""}]
   (m/scan {:farm _ & ?rest})
  {:farm "b" & ?rest})

jimmy 2020-07-23T14:05:42.160600Z

I'm not 100% sure I followed all of what is going on. I think from what I do understand that you are probably doing the right thing by using cata. That is how we often deal with complicated patterns that need a fresh context for nested matches.

murtaza52 2020-07-23T14:13:13.161900Z

(m/search [[{:a 1} {:c 3}] [{:b 2} {:d 5}]]
  (m/scan [{:as ?row}])
  (assoc ?row :z 1))
the above snippet does not work. I have a collection of collections of maps. In each map I want to add a k/v, how do I write it ?

murtaza52 2020-07-23T14:21:48.162400Z

(m/rewrites [[{:a 1} {:c 3}] [{:b 2} {:d 5}]]
  (m/scan (m/scan {& ?rest}))
  {:z 2 & ?rest})
The above adds the k/v, but doesnt maintain the coll structure, it concats all the collections together.

murtaza52 2020-07-23T14:22:35.162500Z

@jimmy thanks, let me try to wrap my head around rewrite/rewrites, when do I use it, it looks very similar to match/search ?

jimmy 2020-07-23T14:26:34.162700Z

So both rewrite and rewrites use m/subst on the right hand side. If you think about pattern matching as deconstructing values, substitution is the constructing of values. Basically it extends many of meanders features for creating things as well as matching on them. To make it concrete, instead of rewrites I could have just said:

(m/search [{:farm ""}
             {:farm "a"}
             {:farm ""}]
   (m/scan {:farm _ & ?rest})
  (m/subst
    {:farm "b" & ?rest}))

murtaza52 2020-07-23T14:28:32.162900Z

cool thanks

noprompt 2020-07-23T17:07:25.163300Z

(m/rewrite [[{:a 1} {:c 3}] [{:b 2} {:d 5}]]
  [(m/cata !xs) ...]
  [!xs ...]

  {:as ?it}
  {:z 2 & ?it})
;; =>
[[{:a 1, :z 2} {:c 3, :z 2}] [{:b 2, :z 2} {:d 5, :z 2}]]

murtaza52 2020-07-26T18:53:47.272100Z

@noprompt how do I make the above work if my input is [(...)(...)] ie a vector of seqs instead of a vector of vectors.

noprompt 2020-07-26T20:17:32.273Z

@murtaza52 Switch to (m/seqable …)

noprompt 2020-07-26T20:18:18.273200Z

Actually, you may need to look at the implementation of that and create your own m/sequential because m/seqable looks for any seqable? thing and calls seq on it.

noprompt 2020-07-23T17:09:07.163700Z

@murtaza52 ☝️

noprompt 2020-07-23T17:12:27.165600Z

One rule to rewrite vectors (recursively rewriting their members), and one to rewrite maps.

noprompt 2020-07-23T17:22:41.169700Z

Meander has some built-in resistance to complex movements, in particular update “in place”. If you find yourself trying to figure out how to do a transform in one fell swoop, break it up in to more focused rules and use m/cata to drive the traversal, etc.

murtaza52 2020-07-24T17:14:28.179300Z

@noprompt thanks ! had not used cata before, so that was a wow moment !

noprompt 2020-07-23T21:37:03.172200Z

Hey folks, I’ve pushed up the some work I’ve been doing to make it possible to dynamically create pattern search interpreters. https://github.com/noprompt/meander/pull/128

3🙂
noprompt 2020-07-23T21:40:32.175Z

It’s not quite ready to merge. In the spirit of including the community to the extent I can, I’m welcoming feedback both here and on the PR.

noprompt 2020-07-23T21:42:41.176700Z

It’ll at least be another couple weeks before this will get merged. In the mean time I plan to address the regression recently pointed out and smooth out any rough edges I see.

noprompt 2020-07-23T21:45:28.179200Z

Questions are welcome. I know some have mentioned a desire to understand how the semantics are implemented in code and I said that I think an interpreter can help with that. If there’s still confusion, I’m happy to walk through it.