Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unexpected behavior using group-by and post-combine together #10

Open
kasperlanger opened this issue Aug 14, 2015 · 6 comments
Open

Unexpected behavior using group-by and post-combine together #10

kasperlanger opened this issue Aug 14, 2015 · 6 comments

Comments

@kasperlanger
Copy link

I was hoping to extend the group-by example with a (post-combine inc) like this

(->> (t/group-by :type)
     (t/map :mass)
     (t/max)
     (t/post-combine inc)
     (t/tesser [[{:name :electron, :type :lepton, :mass 0.51}
                 {:name :muon,     :type :lepton, :mass 105.65}
                 {:name :up,       :type :quark,  :mass 1.5}
                 {:name :down,     :type :quark,  :mass 3.5}]]))
; => {:lepton 106.65, :quark 4.5}

However it raises an exception because the post-combine is added to the top of the fold and inc doesn't like to post-combine the group-by result.

@aphyr
Copy link
Owner

aphyr commented Aug 14, 2015

Hmm, yeah that is a tough one, because often you do want the post-combine to operate on the results of the group-by, but your confusion is certainly legitimate!

The easy workaround here is (t/post-combine (partial tesser.utils/map-vals inc)), I suppose.

@kasperlanger
Copy link
Author

One problem with the workaround is that you quickly end up with transformations that doesn't compose.

An example is trying to use group-by and range together like

 (->> (t/group-by :name)                                                                                                                                                                                                                                   
      (t/map :score)                                                                                                                                                                                                                                       
      (t/range)                                                                                                                                                                                                                                            
      (t/tesser [[{:name "Kasper" :score 21}                                                                                                                                                                                                               
                  {:name "Kasper" :score 22}                                                                                                                                                                                                               
                  {:name "Kyle" :score 42}]]))  
; => [nil nil]

@aphyr
Copy link
Owner

aphyr commented Aug 14, 2015

That's a great objection. Can you find a coherent way to fix it? I'd love to put time into this right now but I've got some other things going on. Happy to see a PR though!

@kasperlanger
Copy link
Author

I'll give it a try. My best bet is changing group-by to use compile-fold like fuse.
Then the above example would look like

(->> (t/group-by' :name
                  (->> (t/map :score)                                                                                                                                                                    
                       (t/range))                                                                                                                                                                                                                                            
     (t/tesser [[{:name "Kasper" :score 21}                                                                                                                                                                                                               
                 {:name "Kasper" :score 22}                                                                                                                                                                                                               
                 {:name "Kyle" :score 42}]]))  

What's your feelings on that approach?

@kasperlanger
Copy link
Author

And another example with post-combine at different stages

(->> (t/group-by :type
                 (->> (t/map :mass)
                      (t/max)
                      (t/post-combine inc))
     (t/post-combine #(assoc % :foo :bar)
     (t/tesser [[{:name :electron, :type :lepton, :mass 0.51}
                 {:name :muon,     :type :lepton, :mass 105.65}
                 {:name :up,       :type :quark,  :mass 1.5}
                 {:name :down,     :type :quark,  :mass 3.5}]]))

; => {:lepton 106.65, :quark 4.5, :foo :bar}

@sbelak
Copy link

sbelak commented Nov 29, 2015

kasperlanger's solution seems neat (a pathetic "me to" until I wrap my head around Tesser enough to produce a PR).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants