partial: Fix a Number of Arguments to a Function

Description Usage Arguments Details Value Examples

Description

partial() enables partial application: given a function, it fixes the value of selected arguments to produce a function of the remaining arguments.

departial() “inverts” the application of partial() by returning the original function.

Usage

1
2
3
partial(..f, ...)

departial(..f)

Arguments

..f

Function.

...

Argument values of ..f to fix, specified by name or position. Captured as quosures. Unquoting and splicing are supported (see ‘Examples’).

Details

Even while partial() truncates formals, it remains compatible with functions that use missing() to test whether a specified argument was supplied in a call. For example, draw3 <- partial(sample, size = 3) works as a function that randomly draws three elements, even though sample() invokes missing(size) and draw3() has signature function (x, replace = FALSE, prob = NULL).

Because partially applied functions call the original function in an ad hoc environment, impure functions that depend on the calling context as a value, rather than as a lexical scope, may not be amenable to partial(). For example, partial(ls, all.names = TRUE)() is not equivalent to ls(all.names = TRUE), because ls() inspects the calling environment to produce its value, whereas partial(ls, all.names = TRUE)() calls ls(all.names = TRUE) from an (ephemeral) execution environment.

Value

partial() returns a function whose formals are a literal truncation of the formals of ..f() (as a closure) by the fixed arguments. partial(..f) is identical to ..f.

In conformance with R's calling convention, fixed argument values are lazy promises. Moreover, when forced, they are tidily evaluated. Lazy evaluation of fixed arguments can be overridden via unquoting, see ‘Examples’.

Examples

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# Arguments can be fixed by name
draw3 <- partial(sample, size = 3)
draw3(letters)

# Arguments can be fixed by position
draw3 <- partial(sample, , 3)
draw3(letters)

# Use departial() to recover the original function
stopifnot(identical(departial(draw3), sample))

# Lazily evaluate argument values by default
# The value of 'n' is evaluated whenever rnd() is called.
rnd <- partial(runif, n = rpois(1, 5))
replicate(4, rnd(), simplify = FALSE)   # variable length

# Eagerly evaluate argument values with unquoting (`!!`)
# The value of 'n' is fixed when 'rnd_eager' is created.
rnd_eager <- partial(runif, n = !!rpois(1, 5))
len <- length(rnd_eager())
reps <- replicate(4, rnd_eager(), simplify = FALSE)   # constant length
stopifnot(all(vapply(reps, length, integer(1)) == len))

# Mix evaluation schemes by combining lazy evaluation with unquoting (`!!`)
# Here 'n' is lazily evaluated, while 'max' is eagerly evaluated.
rnd_mixed <- partial(runif, n = rpois(1, 5), max = !!sample(10, 1))
replicate(4, rnd_mixed(), simplify = FALSE)

# Arguments to fix can be spliced
args_eager <- list(n = rpois(1, 5), max = sample(10, 1))
rnd_eager2 <- partial(runif, !!!args_eager)
replicate(4, rnd_eager2(), simplify = FALSE)

args_mixed <- rlang::exprs(n = rpois(1, 5), max = !!sample(10, 1))
rnd_mixed2 <- partial(runif, !!!args_mixed)
replicate(4, rnd_mixed2(), simplify = FALSE)

# partial() truncates formals by the fixed arguments
foo <- function(x, y = x, ..., z = "z") NULL
stopifnot(
  identical(
    formals(partial(foo)),
    formals(foo)
  ),
  identical(
    formals(partial(foo, x = 1)),
    formals(function(y = x, ..., z = "z") {})
  ),
  identical(
    formals(partial(foo, x = 1, y = 2)),
    formals(function(..., z = "z") {})
  ),
  identical(
    formals(partial(foo, x = 1, y = 2, z = 3)),
    formals(function(...) {})
  )
)

gestalt documentation built on June 27, 2019, 5:08 p.m.