Those two functions don't give the same output, because of how works the %>% operator, but I can't understand why?
my_function <- function(x) {
# Extract the name of x
the_name_of_x <- deparse(substitute(x))
print(the_name_of_x)
}
my_other_function <- function(x) {
# Extract the name of x
the_name_of_x <- x %>% substitute() %>% deparse()
print(the_name_of_x)
}
# Example
my_function("zaza")
# [1] "\"zaza\""
my_other_function("zaza")
# [1] "x"
I really can't figure out why this makes a difference.
You would get the same value as the first one if you used the native pipe
yet_another_function <- function(x) {
# Extract the name of x
the_name_of_x <- x |> substitute() |> deparse()
print(the_name_of_x)
}
The reason is the |>
pipe actually re-writes the syntax tree so it's not actually a function. Observe
quote(x |> substitute() |> deparse())
deparse(substitute(x))
However %>%
is a function. It will appear on the call stack. The substitute
function uses non-standard evaluation which means it looks at the expression passed to the function. The %>%
function cannot re-write the call completely. It evaluates the promise of the function parameter into an expression. substitute
is a special function in that if you want to capture the value a promise points to, you need to do so before the promise is evaluated.
You can see the source of the magrittr pipe function
`%>%`
function (lhs, rhs)
{
lhs <- substitute(lhs)
rhs <- substitute(rhs)
kind <- 1L
env <- parent.frame()
lazy <- TRUE
.External2(magrittr_pipe)
}
And you can see how it's already using substitute
to get the unevaluated expressions of it's parameters. A promise cannot survive this indirection.