as_function()
transforms a one-sided formula into a function.
This powers the lambda syntax in packages like purrr.
as_closure()
first passes its argument to as_function()
. If
the result is a primitive function, it regularises it to a proper
closure (see is_function()
about primitive functions). Some
special control flow primitives like if
, for
, or break
can't be coerced to a closure.
as_function(x, env = caller_env()) is_lambda(x) as_closure(x, env = caller_env())
x | A function or formula. If a function, it is used as is. If a formula, e.g. Lambdas currently do not support nse-force, due to the way the arguments are handled internally. |
---|---|
env | Environment in which to fetch the function in case |
f <- as_function(~ .x + 1) f(10)#> [1] 11g <- as_function(~ -1 * .) g(4)#> [1] -4h <- as_function(~ .x - .y) h(6, 3)#> [1] 3# Functions created from a formula have a special class: is_lambda(f)#> [1] TRUEis_lambda(as_function(function() "foo"))#> [1] FALSE# Primitive functions are regularised as closures as_closure(list)#> function (...) #> .Primitive("list")(...)as_closure("list")#> function (...) #> .Primitive("list")(...)# Operators have `.x` and `.y` as arguments, just like lambda # functions created with the formula syntax: as_closure(`+`)#> function (e1, e2, .x = e1, .y = e2) #> { #> if (missing(.x)) { #> if (missing(e1)) { #> abort("Must supply `e1` or `.x` to binary operator") #> } #> .x <- e1 #> } #> else if (!missing(e1)) { #> abort("Can't supply both `e1` and `.x` to binary operator") #> } #> if (missing(.y) && !missing(e2)) { #> .y <- e2 #> } #> else if (!missing(e2)) { #> abort("Can't supply both `e2` and `.y` to binary operator") #> } #> if (missing(.y)) #> .x #> else .x + .y #> } #> <environment: 0x7fe2f5a23b60>as_closure(`~`)#> function (.x, .y) #> { #> if (is_missing(substitute(.y))) { #> new_formula(NULL, substitute(.x), caller_env()) #> } #> else { #> new_formula(substitute(.x), substitute(.y), caller_env()) #> } #> } #> <bytecode: 0x7fe2f385e5d0> #> <environment: 0x7fe2f5aa6378># Use a regular function for tidy evaluation, also when calling functions # that use tidy evaluation: ## Bad: e <- as_function(~ as_label(ensym(.x))) ## Good: e <- as_function(function(x) as_label(ensym(x))) e(y)#> [1] "y"