R: Collect dots tidily

tidy-dots {rlang} | R Documentation

## Collect dots tidily

### Description

`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.

### Usage

    dots_list(..., .ignore_empty = c("trailing", "none", "all"))

    list2(...)

### Arguments

`...` | Arguments with explicit (`dots_list()`) or list (`dots_splice()`) splicing semantics. The contents of spliced arguments are embedded in the returned list.
`.ignore_empty` | Whether to ignore empty arguments. Can be one of `"trailing"`, `"none"`, `"all"`. If `"trailing"`, only the last argument is ignored if it is empty.

### Details

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.

### Value

A list of arguments. This list is always named: unnamed arguments are named with the empty string `""`.

### Life cycle

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.

### See Also

`exprs()` for extracting dots without evaluation.

### Examples

    # 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

[Package rlang version 0.2.2 Index]