tidyverse / magrittr

Improve the readability of R code with the pipe
https://magrittr.tidyverse.org
Other
957 stars 157 forks source link

Pipes of functions have broken environments #159

Closed HuwCampbell closed 4 years ago

HuwCampbell commented 6 years ago

Sorry if this appears a little obscure, it's causing me some difficulty.

I found this issue after you posted a review for hedgehog (ta!). Using the pipe I was having infinite recursion due to the environments being brought into functions incorrectly.

Here's a quick bug showing something similar

compose <- function(f, g) { function(x) g(f(x)) }
plus1   <- function(x) x + 1
compose(plus1, plus1)(5)
# [1] 7
plus2 <- plus1 %>% compose(plus1)
plus2(5)
# Error in g(f(x)) : could not find function "f"
plus2
# function(x) g(f(x))
# <environment: 0x7f977ecd1ea8>
as.list(environment(plus2))
# $f
# $f$value
# function (x) 
# g(f(x))
# <environment: 0x7f977ecd1ea8>
# 
# $f$visible
# [1] TRUE

# $g
# function (x) 
# x + 1

See above that f$value refers to g(f(x)), when it should be function(x) x + 1.

HuwCampbell commented 6 years ago

Might be a duplicate of #146 but I can't tell

stefanbache commented 6 years ago

Noted. It does work in the update branch, which uses a different approach. I'm behind on giving this attention, hope to get some time for this soon.

lionel- commented 4 years ago

This is not a problem of environment but of lazy evaluation. Forcing the inputs solves the problem:

compose <- function(f, g) { force(f); force(g); function(x) g(f(x)) }

plus2 <- plus1 %>% compose(plus1)
plus2(5)
#> [1] 7

See also #195.

lionel- commented 4 years ago

Fixed by #218