
The goal of factory is to make construction of function factories
more straightforward, without requiring the user to learn the
rlang package.
You can install factory from GitHub with:
# install.packages("remotes")
remotes::install_github("jonthegeek/factory")Function factories are functions that make functions. They can be confusing to work with. For example, they can produce functions that are fragile (examples from Advanced R by Hadley Wickham (2nd Edition), 10.2.3: Forcing Evaluation, “Gah” comments are me):
power1 <- function(exponent) {
function(x) {
x ^ exponent
}
}
x <- 2
square1 <- power1(x)
x <- 3
square1(2) # Gah, fragile!
#> [1] 8You can make factories that are less fragile, if you remember to
force the variables.
power2 <- function(exponent) {
force(exponent) # Gah, easy to forget!
function(x) {
x ^ exponent
}
}
x <- 2
square2 <- power2(x)
x <- 3
square2(2)
#> [1] 4However, the resulting function can be hard to understand:
square2
#> function(x) {
#> x ^ exponent
#> }
#> <environment: 0x00000000163e5650>You can make functions that are easier to understand, but building the function factory is much more difficulty (from Advanced R by Hadley Wickham (2nd Edition), 19.7.4: Creating functions):
power3 <- function(exponent) {
rlang::new_function(
rlang::exprs(x = ),
rlang::expr({
x ^ !!exponent
}),
rlang::caller_env()
)
}The resulting functions look like a “normal” function, though, and are thus easier for users to understand:
square3 <- power3(2)
square3
#> function (x)
#> {
#> x^2
#> }The goal of factory is to make function factories as
straightforward to create as in power1, but to make the
resulting functions make as much sense as in power3:
library(factory)
power4 <- build_factory(
fun = function(x) {
x ^ exponent
},
exponent
)
x <- 2
square4 <- power4(x)
x <- 3
square4(2)
#> [1] 4The resulting function is clear, as with power3:
square4
#> function (x)
#> {
#> x^2
#> }