meander

All things about https://github.com/noprompt/meander Need help and no one responded? Feel free to ping @U5K8NTHEZ
noprompt 2020-03-29T00:02:55.036800Z

In this case the usual recommendation is to do the group-by first and then your processing after.

(let [data [{:class :a, :numbers [10], :count? true} 
            {:class :b :numbers [3], :count? true} 
            {:class :a, :numbers [88], :count? true}]]
  (m/find (group-by :class data)
    {?class [(m/or {:numbers [!nums ...] :count? true} _) ...] & (m/cata ?rest)}
    (cons {:class ?class :numbers (reduce + !nums) :count? true} ?rest)

    {}
    ()))
;; =>
({:class :a, :numbers 98, :count? true}
 {:class :b, :numbers 3, :count? true})

noprompt 2020-03-29T00:05:20.038900Z

Aggregation is something that comes up a lot and we will have something specifically for it available by summer (along with other things).

JAtkins 2020-03-29T02:26:15.039100Z

Thanks for the tip!

yuhan 2020-03-29T11:52:02.041600Z

I spent some time tracking down a bug last week that turned out to be due to my use of the (and !memvar1 !memvar2) method from the cookbook for re-using a memvar in two different places in the output pattern, coupled with the ..!n syntax

yuhan 2020-03-29T11:54:38.043500Z

something like [(m/and !m1 !m2) ..!n] -> {:a [!m1 ..!n] :b [!m2 ..!n]} , except nested in a much more complicated pattern

yuhan 2020-03-29T11:58:54.045500Z

The bug was pretty obvious once discovered but it occured to me that such constructs can be pretty hard to reason about in subtle ways.. with an imperative flavour of pushing and popping from arrays and keeping track of indices

yuhan 2020-03-29T14:33:08.048600Z

The next logical step is asking whether there exists some sort of ..(and !n1 !n2) syntax , but that just seems like a further step in the wrong direction..

yuhan 2020-03-29T14:35:28.050700Z

really the [[!x ..!n] ...] syntax is a way of fitting multidimensional data into a linear memory variable, I wonder if there could be a less clunky way of encoding this

jimmy 2020-03-29T16:34:46.054100Z

With fold and unfold we will have more power to implement better ways of doing these things. But my recommendation is also to dream up your ideal way and share it. Maybe it will be implemented or maybe it will spark other with more ideas.

noprompt 2020-03-29T16:44:17.055900Z

Ideas are absolutely welcome.

niclasnilsson 2020-03-29T17:20:33.057800Z

Question about variable number of forms:

;; This works:
(def data
  '((path "/a" 
          (PUT "Updates A"))
    (path "/b" 
          (GET "Gets a B"))))

(m/rewrite 
  data
  ((path !path (!method !desc)) ..!paths)
  [{:path !path
    :routes 
    {:method !method
     :desc !desc}} ..!paths])
  
;; But this was harder, when adding more routes to a path:
(def data
  '((path "/a" 
          (PUT "Updates A"))
    (path "/b" 
          (PUT "Gets a B")
          (PUT "Updates B"))))

;; Desired output
[{:path "/a" :routes [{:method 'PUT :desc "Updates A"}]}
 {:path "/b" :routes [{:method 'GET :desc "Gets a B"}
                      {:method 'PUT :desc "Updates B"}]}] 
I’ve tried to make it seqable and some other things, but can’t find the way to make this work. What am I missing?

noprompt 2020-03-29T18:15:45.058900Z

@niclasnilsson

(let [data
      '((path "/a" 
              (PUT "Updates A"))
        (path "/b" 
              (PUT "Gets a B")
              (PUT "Updates B")))]
  (m/rewrite 
    data
    ((path !path . (!method !desc) ..!routes) ..!paths)
    [{:path !path
      :routes [{:method !method
                :desc !desc} ..!routes]} ..!paths]))
;; =>
[{:path "/a",
  :routes [{:method PUT, :desc "Updates A"}]}
 {:path "/b",
  :routes [{:method PUT, :desc "Gets a B"}
           {:method PUT, :desc "Updates B"}]}]

noprompt 2020-03-29T18:27:36.060200Z

Keep in mind you can always use cata to do nested transforms with separate rules rather than all in one shot.

niclasnilsson 2020-03-29T18:44:19.061300Z

Ah… I was more or less in dot from finding the solution then! Close, but no cigar! 🙂 Thank you very much, @noprompt!

👍 1