Skip to content

The base ... syntax supports:

  • Forwarding arguments from function to function, matching them along the way to arguments.

  • Collecting arguments inside data structures, e.g. with c() or list().

Dynamic dots offer a few additional features, injection in particular:

  1. You can splice arguments saved in a list with the splice operator !!!.

  2. You can inject names with glue syntax on the left-hand side of :=.

  3. Trailing commas are ignored, making it easier to copy and paste lines of arguments.

Add dynamic dots support in your functions

If your function takes dots, adding support for dynamic features is as easy as collecting the dots with list2() instead of list(). See also dots_list(), which offers more control over the collection.

In general, passing ... to a function that supports dynamic dots causes your function to inherit the dynamic behaviour.

In packages, document dynamic dots with this standard tag:

 @param ... <[`dynamic-dots`][rlang::dyn-dots]> What these dots do.


f <- function(...) {
  out <- list2(...)

# Trailing commas are ignored
f(this = "that", )
#> $this
#> [1] "that"

# Splice lists of arguments with `!!!`
x <- list(alpha = "first", omega = "last")
#> $omega
#> [1] "last"
#> $alpha
#> [1] "first"

# Inject a name using glue syntax
if (is_installed("glue")) {
  nm <- "key"
  f("{nm}" := "value")
  f("prefix_{nm}" := "value")
#> $prefix_key
#> [1] "value"