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")
::install_github("jonthegeek/factory") remotes
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):
<- function(exponent) {
power1 function(x) {
^ exponent
x
}
}
<- 2
x <- power1(x)
square1
<- 3
x square1(2) # Gah, fragile!
#> [1] 8
You can make factories that are less fragile, if you remember to
force
the variables.
<- function(exponent) {
power2 force(exponent) # Gah, easy to forget!
function(x) {
^ exponent
x
}
}
<- 2
x <- power2(x)
square2 <- 3
x square2(2)
#> [1] 4
However, 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):
<- function(exponent) {
power3 ::new_function(
rlang::exprs(x = ),
rlang::expr({
rlang^ !!exponent
x
}), ::caller_env()
rlang
) }
The resulting functions look like a “normal” function, though, and are thus easier for users to understand:
<- power3(2)
square3
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)
<- build_factory(
power4 fun = function(x) {
^ exponent
x
},
exponent
)
<- 2
x <- power4(x)
square4 <- 3
x square4(2)
#> [1] 4
The resulting function is clear, as with power3:
square4#> function (x)
#> {
#> x^2
#> }