posure {gestalt} | R Documentation |
Variable Composite Functions
Description
posure()
enables you to create efficient variable (i.e., parameterized)
composite functions.
For instance, say you have a composite function such as
function(..., b = 2, n) { (sample %>>>% log(base = b) %>>>% rep(n))(...) } # Alternatively, expressed with the magrittr %>%: function(..., b = 2, n) { sample(...) %>% log(base = b) %>% rep(n) }
which varies according to the values of b
and n
. You can express this
more succinctly with posure()
, by dropping the placeholder argument
(‘...
’):
posure(b = 2, n ~ { sample %>>>% log(base = b) %>>>% rep(n) })
This creates a function with same formals and return values.
But the posure()
version is more efficient because it creates the composite
function just once, rather than anew with each function call. Morever, it
is robuster than the functionally equivalent construction with the
magrittr `%>%`
because posure()
validates the constituent functions (see
‘Examples’).
Usage
posure(..., ..env = parent.frame())
Arguments
... |
Function declaration whose body must be a function composition
expressed using |
..env |
Environment in which to create the function. (You should rarely need to set this.) |
Details
posure()
curries composite
functions. However, the main significance of posure()
is its efficiency,
which is achieved via non-standard scoping semantics (transparent to the
caller). posure()
creates the given composite function once. When the
resulting variable composite function is called, its dependencies are
dynamically bound to its localized lexical scope, for fast lookup, then
removed when the function exits. Thus a posure is a (parameterized)
closure that is partially dynamically scoped. (This
portmanteau is due to Henry Stanley.)
Value
Function with formals
function (..., <composite_function_dependencies>)
, where
<composite_function_dependencies>
stands for the formals captured by the
dots of posure()
. In particular, a call of the form
posure(a, b = value ~ f(a, b) %>>>% g(a, b))
produces a function with the same formals and return values as
function(..., a, b = value) { (f(a, b) %>>>% g(a, b))(...) }
See Also
Examples
foo <- posure(b = 2, n ~ {
sample %>>>% log(base = b) %>>>% rep(n)
})
# A posure is a composite function with dependencies:
foo
set.seed(1)
foo(2^(1:10), size = 2, n = 3)
#> [1] 3 4 3 4 3 4
set.seed(1)
rep(log(sample(2^(1:10), size = 2), base = 2), 3)
#> [1] 3 4 3 4 3 4
# However, a 'posure()' does the composition upfront, so it is faster
# than the equivalent function defined using the magrittr pipe:
library(magrittr) # Provides the pipe %>%
foo_pipe <- function(..., b = 2, n) {
sample(...) %>% log(base = b) %>% rep(n)
}
set.seed(1)
foo_pipe(2^(1:10), size = 2, n = 3)
#> [1] 3 4 3 4 3 4
# Moreover, posures are safer than functions defined using the pipe,
# because '%>>>%' validates constituent functions:
try(posure(b = 2, n ~ log(Base = b) %>>>% rep(n)))
# Error: unused argument (Base = b)
try(posure(b = 2 ~ my_sample %>>>% log(base = b)))
# Error: object 'my_sample' not found