tidy-dots {rlang} | R Documentation |
list2()
is equivalent to list(...)
but provides tidy
dots semantics:
You can splice other lists with the
unquote-splice !!!
operator.
You can unquote names by using the unquote
operator !!
on the left-hand side of :=
.
We call quasiquotation support in dots tidy dots semantics and
functions taking dots with list2()
tidy dots functions.
Quasiquotation is an alternative to do.call()
idioms and gives
the users of your functions an uniform syntax to supply a variable
number of arguments or a variable name.
dots_list()
is a lower-level version of list2()
that offers
additional parameters for dots capture.
dots_list(..., .ignore_empty = c("trailing", "none", "all"), .preserve_empty = FALSE, .homonyms = c("keep", "first", "last", "error"), .check_assign = FALSE) list2(...)
... |
Arguments to collect with |
.ignore_empty |
Whether to ignore empty arguments. Can be one
of |
.preserve_empty |
Whether to preserve the empty arguments that
were not ignored. If |
.homonyms |
How to treat arguments with the same name. The
default, |
.check_assign |
Whether to check for |
Note that while all tidy eval quoting functions have
tidy dots semantics, not all tidy dots functions are quoting
functions. list2()
is for standard functions, not quoting
functions.
A list of arguments. This list is always named: unnamed
arguments are named with the empty string ""
.
One difference of dots_list()
with list2()
is that it always
allocates a vector of names even if no names were supplied. In this
case, the names are all empty ""
. This is for consistency with
enquos()
and enexprs()
but can be quite costly when long lists
are spliced in the results. For this reason we plan to parameterise
this behaviour with a .named
argument and possibly change the
default. list2()
does not have this issue.
exprs()
for extracting dots without evaluation.
# Let's create a function that takes a variable number of arguments: numeric <- function(...) { dots <- list2(...) num <- as.numeric(dots) set_names(num, names(dots)) } numeric(1, 2, 3) # The main difference with list(...) is that list2(...) enables # the `!!!` syntax to splice lists: x <- list(2, 3) numeric(1, !!! x, 4) # As well as unquoting of names: nm <- "yup!" numeric(!!nm := 1) # One useful application of splicing is to work around exact and # partial matching of arguments. Let's create a function taking # named arguments and dots: fn <- function(data, ...) { list2(...) } # You normally cannot pass an argument named `data` through the dots # as it will match `fn`'s `data` argument. The splicing syntax # provides a workaround: fn("wrong!", data = letters) # exact matching of `data` fn("wrong!", dat = letters) # partial matching of `data` fn(some_data, !!!list(data = letters)) # no matching # Empty arguments trigger an error by default: try(fn(, )) # You can choose to preserve empty arguments instead: list3 <- function(...) dots_list(..., .preserve_empty = TRUE) # Note how the last empty argument is still ignored because # `.ignore_empty` defaults to "trailing": list3(, ) # The list with preserved empty arguments is equivalent to: list(missing_arg()) # Arguments with duplicated names are kept by default: list2(a = 1, a = 2, b = 3, b = 4, 5, 6) # Use the `.homonyms` argument to keep only the first of these: dots_list(a = 1, a = 2, b = 3, b = 4, 5, 6, .homonyms = "first") # Or the last: dots_list(a = 1, a = 2, b = 3, b = 4, 5, 6, .homonyms = "last") # Or raise an informative error: try(dots_list(a = 1, a = 2, b = 3, b = 4, 5, 6, .homonyms = "error")) # dots_list() can be configured to warn when a `<-` call is # detected: my_list <- function(...) dots_list(..., .check_assign = TRUE) my_list(a <- 1) # There is no warning if the assignment is wrapped in braces. # This requires users to be explicit about their intent: my_list({ a <- 1 })