meander

All things about https://github.com/noprompt/meander Need help and no one responded? Feel free to ping @U5K8NTHEZ
dominicm 2019-12-05T09:00:44.331700Z

My current m/rewrite-like code uses a walk and an atom. The atom is state that I update to indicate where I have rewritten in order to correct adjacent nodes. I'm wondering what my options are with meander.

dominicm 2019-12-05T09:21:41.331800Z

I'm guessing a custom strategy might work.

dominicm 2019-12-05T10:05:01.331900Z

Is it expected that bottom-up loses metadata? top-down doesn't seem to (but it might do, just not from a position I care about)

dominicm 2019-12-05T14:36:19.332100Z

Looks like all doesn't preserve metadata.

dominicm 2019-12-05T15:23:36.332300Z

I've opened a PR. Happy to be told "no" :) Love how extensible meander is with syntax & strategies, means I can solve this for me if it's not appropriate upstream.

ingesol 2019-12-05T17:08:46.334400Z

Hi! I’m learning meander as a beginner, experimenting with a list of maps, containing nested maps. Some of the maps are missing the key for the nested maps, but I still want to match on them. When I do it like the source code below, the second element is unmatched. How can I define :prop2 as an optional match?

(m/search
 [{:prop1 "x1"
   :prop2 {:prop3 {:prop4 "y"}}}
  {:prop1 "x2"}]
 (m/scan
  {:prop1 ?prop1
   :prop2 {:prop3 {:prop4 ?y}}})
 {:prop1 ?prop1
  :y     ?y})

dominicm 2019-12-05T17:10:29.334900Z

I think you can use m/or with m/let

dominicm 2019-12-05T17:10:54.335700Z

You'll need a value for y somehow if I remember correctly

ingesol 2019-12-05T17:36:21.337Z

@dominicm Tried playing with the code in that direction, but not immediately clear to me how to combine those

dominicm 2019-12-05T17:37:57.337300Z

The problem you'll have is that you need to bind ?y somehow (That's where m/let comes in!)

noprompt 2019-12-05T18:12:52.337400Z

I’m happiest when people send me patches. 🙂

jimmy 2019-12-05T18:18:44.337900Z

(m/search
  [{:prop1 "x1"
    :prop2 {:prop3 {:prop4 "y"}}}
   {:prop1 "x2"}]
  (m/scan
   {:prop1 ?prop1
    :prop2 (m/or 
            {:prop3 {:prop4 ?y}}
            (m/let [?y 0] nil))})
  {:prop1 ?prop1
   :y ?y})

dominicm 2019-12-05T18:18:48.338Z

I try :)

jimmy 2019-12-05T18:21:14.340600Z

What we need to do is make sure that we always have our logic variables bound. So ?y needs to be bound to something. In this case I just made it zero. But we also need the nil there because of how search works. Search looks for all possible ways to match. So without the nil, we would get these results.

({:prop1 "x1", :y "y"} {:prop1 "x1", :y 0} {:prop1 "x2", :y 0})
Without nil, both branches of our or can match, so we will get back both ways of matching.

jimmy 2019-12-05T18:21:30.341Z

(nil here means that if we look up the key in the map, we will get nil)

jimmy 2019-12-05T18:22:38.341400Z

You could also move the or out a level.

(m/search
  [{:prop1 "x1"
    :prop2 {:prop3 {:prop4 "y"}}}
   {:prop1 "x2"}]
  (m/scan
   (m/or
    {:prop1 ?prop1
     :prop2 {:prop3 {:prop4 ?y}}}

    (m/let [?y 0]
      {:prop1 ?prop1
       :prop2 nil})))
  {:prop1 ?prop1
   :y ?y})

noprompt 2019-12-05T18:22:53.341700Z

You sent me a few! 😄

jimmy 2019-12-05T18:23:02.342100Z

@ingesol ^

noprompt 2019-12-05T18:23:56.342200Z

I’ll get a release out here w/in the next couple hours. I need to walk back some of the changes I made to the rewrite stuff as its not fully baked. I made the mistake of commit to epsilon and just kinda procrastinated undoing it. 😛

dominicm 2019-12-05T19:03:49.342500Z

I have a cli for opening prs, my workflow is pretty lightweight on top of it. I can sneeze and send a pr.

noprompt 2019-12-05T19:25:21.342700Z

Do you have something to share on that front? That sounds cool!

dominicm 2019-12-05T19:32:26.342900Z

Basically just hub cli

dominicm 2019-12-05T19:33:03.343100Z

https://github.com/github/hub

dominicm 2019-12-05T19:33:29.343400Z

Fork followed by pull request will pop open vim with a pr prefilled with the last commit

dominicm 2019-12-05T19:34:01.343600Z

I have to push to my remote, but that's in my muscle memory now. Hub gives it a consistent name.

ingesol 2019-12-05T21:35:07.346600Z

@jimmy @dominicm Thanks, this really helps! So in general, when I have an optional key, the pattern is this:

(m/or ?foo
  (m/let [?foo nil]
    nil))
Which is understandable and all is well. Was just wondering if there is some specific syntax for the case of simple optional map keys (not nested)

jimmy 2019-12-05T23:32:22.350Z

By default simple keys are optional. If you match with a logic variable on a key that doesn't exist. You will get nil bound to that variable.

jimmy 2019-12-05T23:33:31.351200Z

There reason to doesn't work here is because you are matching something more specific than a logic variable. The pattern asserts that prop2 should be a map.