Search code examples
rpurrrmagrittr

Sample function doesn't work well with purrr::rerun and pipe?


I observed some weird behavior in purrr::rerun when it's used with %>% that I couldn't understand.

If I run,

library(purrr)
sample(1:30, 3) %>% rerun(4, .)

it will return,

# 1 24 5
# 1 24 5
# 1 24 5
# 1 24 5

clearly it's not what I want.

However, if I run a similar code without %>%, it will actually work as expected.

rerun(4, sample(1:30, 3))
# 17 5 20
# 13 3 6
# 22 25 3
# 20 30 29

I couldn't understand why the behavior is different. Can someone explain? Thanks in advance.


Solution

  • magrittr doesn't evaluate the dots lazily. It might very well have, as in this mock pipe (don't use it it will break easily!)

    `%foo>%` <- function(e1,e2){
      eval.parent(eval(substitute(substitute(e2,list(. = substitute(e1))))))
    }
    
    sample(1:30, 3) %foo>% purrr::rerun(4, .)
    #> [[1]]
    #> [1] 22 25  9
    #> 
    #> [[2]]
    #> [1] 14 28 21
    #> 
    #> [[3]]
    #> [1]  4  1 25
    #> 
    #> [[4]]
    #> [1] 17  2 25
    

    Created on 2019-09-19 by the reprex package (v0.3.0)

    It is a design choice, probably made to avoid ambiguities and inefficiency when several dots are used.