meander

All things about https://github.com/noprompt/meander Need help and no one responded? Feel free to ping @U5K8NTHEZ
timothypratley 2020-01-04T00:04:59.225500Z

a) kvseq was needed because there is no ..!n equivalent for maps b) associations is needed to convert memory variables and partitions to rows. I think this might be useful to meander users and hope you consider including something like it in meander. Is it actually as useful as I think it is? Maybe it doesn’t come up much, or maybe if we had substitution equivalents it would be unnecessary. c) nest-by is needed because meander doesn’t have a way of expressing reduction/aggregation.

timothypratley 2020-01-04T00:39:18.226600Z

It’s also very interesting to me that when you put the pattern and associations function side by side you can see clearly that one implies the other:

([!lang ([!num !word] ..!n)] ...)
(associations [!lang] [!num !word] !n)

jimmy 2020-01-04T00:54:28.226800Z

Haven't had a chance to deep dive on this. But you can match maps with seqable. And seqable supports ..!n.

noprompt 2020-01-04T08:29:19.228800Z

[meander/epsilon "0.0.356"]
• Fixes separated patterns producing too many answers when searching • Documentation updates • Add :as pattern keyword arguments to m/keyword and m/symbol

timothypratley 2020-01-04T09:06:27.228900Z

Comparing with the search approach:

(m/search {1 {:en "one", :de "eins", :fr "un"}
            2 {:en "two", :de "zwei", :fr "deux" :es "dos"}
            3 {:en "three", :de "drei", :fr "trois"}
            5 {:fr "cinq"}}
           (m/scan [?num (m/scan [?lang ?word])])
           [?lang ?num ?word])
^^ This finds all the rows without any helpers, has obvious ordering (which means nesting can be even simpler)… maybe the real answer here is you are better off not bothering with memory variables for associative transformations. There is a specific case where you have 2 repeats inside 1 repeat where you can’t use search/scan, but maybe that should be handled by first splitting then search/scanning each separately.

dominicm 2020-01-04T11:18:55.230100Z

This is going to sound pushy, but it's actually half conversational and half curiosity... How's Zeta?

noprompt 2020-01-04T17:21:46.230400Z

I’ve been distracted by issues with epsilon and haven’t had a chance to resume working on zeta. But unless much more comes up, I think its safe to say I’ll resume working on the branch.

noprompt 2020-01-04T17:46:02.230600Z

Here’s a question: should match just be find that throws an error when nothing matches?

noprompt 2020-01-04T17:46:58.231200Z

Whats motivating the curiosity?

jimmy 2020-01-04T19:23:10.232100Z

Personally I don't think so. I like that match is restricted to things that are unambiguous.

dominicm 2020-01-04T19:44:47.232200Z

Talking about code standards internally at work. I'm thinking the update in place will make my work on cinder much easier. But also just seeing the updates to epsilon and realizing I don't entirely understand how you work and transition. Nor do I understand all the goals of Zeta, and if you're reaching them.

noprompt 2020-01-04T20:07:25.232400Z

Basically, until zeta becomes the primary branch, I will continue to address epsilon issues as they come up and I can fix them without breaking existing code. To be clear, I am personally not invested in working on implementing and update-in-place operator because I’m satisfied with cata for that. At the same time, I’m not opposed to having such an operator. @jimmy is interested in this too. Maybe the two of you could work together on a concept/implementation?

noprompt 2020-01-04T20:08:43.232600Z

The goals of zeta are to define a new AST for the syntax and to implement an interpreter/compiler that are semantically equivalent.

dominicm 2020-01-04T20:10:17.232800Z

I thought Zeta made this easier, going to double check what I read 😊

dominicm 2020-01-04T20:15:43.233500Z

Yeah, the hope from Jimmy was that Zeta will bring this in some manner. @jimmy totally happy to describe my problems in excruciating detail and get some guidance on how to solve that.

dominicm 2020-01-04T20:16:28.234700Z

@noprompt what problems do those changes solve?

noprompt 2020-01-04T20:16:39.235200Z

Epsilon could have update in place. There’s nothing stopping us there. Zeta is purely about a better AST, interpreter, and compiler.

dominicm 2020-01-04T20:17:40.236100Z

Yeah, that was my general I interpretation which gets me wanting to work on this sooner.

noprompt 2020-01-04T20:19:06.237800Z

There is plenty of room for additional innovation in the strategy namespace.

noprompt 2020-01-04T20:19:10.238100Z

I welcome that.

jimmy 2020-01-04T20:36:02.238300Z

Yeah I am happy to have someone else to help with brainstorming update in place. I'd love to see some ideas and think about implementation. I'd definitely love to hear about your problems and think about what currently exists and what we could build in epsilon. I said zeta simply because my hope is that it will make building that stuff trivial. (also happy to explain the experiment we are trying with zeta) @dominicm feel free to private message me and we can chat about it (might be busy over the weekend though).

noprompt 2020-01-04T20:42:25.240Z

Please share any good ideas you come up with in the channel. 😀

jimmy 2020-01-04T20:43:20.241500Z

Of course

noprompt 2020-01-04T20:44:26.243Z

One thing that would be really cool and I’ve been wanting is to have a compiled, strategy thingy. Update in place would be nice to have.

aisamu 2020-01-04T21:22:14.250100Z

Hi! I'm giving meander a try on some toy problems - it's a blast! Would it be possible to partition-by sequences with meander? E.g.:

;; 0 is the separator
(meander-magic [1 2 3 0 4 5 6 0 7 8 0 9])
;; => ([1 2 3] [4 5 6] [7 8] [9])
Also, some questions I had while trying to solve this: - Is there a way to make search "consume" input? (not matching what was already caught by a previous search) - Is there a start/`end-of-sequence` marker? (making this example's boundaries simpler) - Is there something akin to Mathematica's Longest/`Shortest` (i.e. https://reference.wolfram.com/language/ref/Longest.html to force "eager" or "lazy" matching)

mmeix 2020-01-05T14:27:09.258300Z

but why not use just partition-by?

aisamu 2020-01-05T18:36:34.266600Z

> if you pre-processed the sequence to add a leading and trailing zero, then extracted all "between-zero" Yup, but I'd call that "cheating" for the purposes of this exercise. (But that's precisely the role I was expecting the start/`end-of-sequence` markers to play) > but why not use just partition-by? We could extend that argument to the whole of meander :)

aisamu 2020-01-05T18:58:08.266800Z

And here's how something like Longest would help (Mathematica - lists are {}, .., ... behave like you'd expect, :> is just a (late) binding):

SequenceCases[list, {0..., els: Longest[Except[0]..], 0...} :> {els}]
=> {{1,2,3},{4,5,6},{7,8},{9}}

jimmy 2020-01-05T22:07:17.277600Z

You could accomplish this with strategies by doing a reduction with them. But other than that I can't think of a way.

1👌
aisamu 2020-01-06T12:28:07.283Z

Thanks! It's still unclear how I'd approach that, though. If you already have the final solution, please don't worry about giving me spoilers :)

jimmy 2020-01-06T15:06:58.283300Z

There is probably a more succinct way, but here is one example.

(def divide-out-zeros
   (r/pipe
    (r/rewrite ?xs [?xs [[]]])
    (r/until =
      (r/rewrite
       [[] ?acc] ?acc
       [[0 & ?xs] [!acc ...]] [?xs [!acc ... . []]]
       [[?x & ?xs] [!acc ... . [!last ...]]] [?xs [!acc ... . [!last ... . ?x]]]))))

(divide-out-zeros [1 2 3 0 4 5 6 0 7 8 0 9])

1🎉
timothypratley 2020-01-06T20:39:23.285800Z

I for one would like to hear more about Longest.

timothypratley 2020-01-06T20:41:19.286Z

Seems like it would be nice to define the break token and non-break using with& can’t appear at the start currently but tere is a proposal to allow that… maybe :as does not bind the vector like I hoped.

timothypratley 2020-01-06T20:43:29.286200Z

oh this works for the last bit only:

(m/find [1 2 3 0 4 5 6 0 7 8 0 9]
        [ ;;& [(pred (complement zero?)) ... :as !x]
         _ ...
         (m/pred zero?) ...
         & [(m/pred (complement zero?)) ... :as !x]]
        !x)

timothypratley 2020-01-06T20:52:18.286400Z

I think I’d like to be able to write:

(m/match [1 2 3 0 4 5 6 0 7 8 0 9]
         (m/with [%break% (pred zero?)
                  %thing% (m/not %break%)]
                 [(m/group (m/group %thing% ... :as !x) . %break% ...) ...])
         !x)
(doesn’t work) or
(m/match [1 2 3 0 4 5 6 0 7 8 0 9]
         (m/with [%break% (pred zero?)
                  %thing% (m/not %break%)]
                 [& [& [%thing% ... :as !x] . %break% ...] ...])
         !x)
(almost but not quite)

timothypratley 2020-01-06T20:57:52.286900Z

it seems one way to look at this is that grouping would solve it, and & provides grouping.

1
jimmy 2020-01-06T21:20:59.287600Z

Figured out a solution with with

(m/rewrite [1 2 3 0 4 5 6 0 7 8 0 9]
  (m/with [%split (m/or [!xs ..!n 0 & %split]
                        [!xs ..!n])]
    %split)
  [[!xs ..!n] ...])

1👀
jimmy 2020-01-06T21:22:31.287900Z

Honestly don't know why I didn't think of this before. It isn't too bad at all.

timothypratley 2020-01-06T21:24:47.288100Z

Oh nice!!!! 🙂

noprompt 2020-01-07T06:47:21.000400Z

(me/search '[a b c d e f g]
 (me/and [!xs ..?i !ys ..?j !zs ..?k]
         (me/guard (and (< ?i ?j)
                        (< ?k ?j))))
  [!xs !ys !zs])
;; =>
([[] [a b c d] [e f g]]
 [[] [a b c d e] [f g]]
 [[] [a b c d e f] [g]]
 [[] [a b c d e f g] []]
 [[a] [b c d e] [f g]]
 [[a] [b c d e f] [g]]
 [[a] [b c d e f g] []]
 [[a b] [c d e] [f g]]
 [[a b] [c d e f] [g]]
 [[a b] [c d e f g] []]
 [[a b c] [d e f g] []])
☝️ Using the example as reference. Note that the search results include the solution given by the example.

1👀
aisamu 2020-01-04T21:23:48.250300Z

Here's the closest I could get, but I can't find my way around the sub-sequences being returned as well

(m/search [1 2 3 0 4 5 6 0 7 8 0 9]
  (m/or
   (m/scan
    (m/pred (complement zero?) !els) ..1
    . (m/pred zero?) ...)
   (m/scan
    (m/pred zero?) ..1
    (m/pred (complement zero?) !els) ..1))
  !els)
;; => ([1] [1 2] [1 2 3] [1 2 3] [2] [2 3] [2 3] [3] [3] [4] [4 5] [4 5 6] [4 5 6] [5] [5 6] [5 6] [6] [6] [7] [7 8] [7 8] [8] [8] [9] [4] [4 5] [4 5 6] [7] [7 8] [9])
NB: It's completely understandable that this might be the wrong tool for the job... but I can't help it.

dominicm 2020-01-04T22:19:28.250500Z

Compiled strategy?