# 8  Put `…` after required arguments

## 8.1 What’s the pattern?

If you use `…` in a function, put it after the required arguments and before the optional arguments.

This has two positive impacts:

• It forces the user of your function to fully name optional arguments, because arguments that come after `...` are never matched by position or by partial name. We believe that using full names for optional arguments is good practice because it makes code easier to read.

• This in turn means that uou can easily add new optional arguments or change the order of existing arguments without affecting existing code.

## 8.2 What are some examples?

The arguments to `mean()` are `x`, `trim`, `na.rm` and `…`. This means that you can write code like this:

``````x <- c(1, 2, 10, NA)
mean(x, , TRUE)
#>  4.333333
mean(x, n = TRUE, t = 0.1)
#>  4.333333``````

Not only does this allow for confusing code1, it also makes it hard to later change the order of these arguments, or introduce new arguments that might be more important.

If `mean()` instead placed `…` before `trim` and `na.rm`, like `mean2()`2 below, then you must fully name each argument:

``````mean2 <- function(x, ..., na.rm = FALSE, trim = 0) {
mean(x, ..., na.rm = na.rm, trim = trim)
}

mean2(x, na.rm = TRUE)
#>  4.333333
mean2(x, na.rm = TRUE, trim = 0.1)
#>  4.333333``````

## 8.3 How do I remediate past mistakes?

It’s straightforward to fix a function where you’ve put `...` in the wrong place: you just need to change the argument order and use `rlang::check_dots_used()` to check that no arguments are lost (learn more in Chapter 23). This is a breaking change, but it tends to affect relatively little code because most people do fully name optional arguments.

We can use this approach to make a safer version of `mean()`:

``````mean3 <- function(x, ..., na.rm = FALSE, trim = 0) {
rlang::check_dots_used()
mean(x, ..., na.rm = na.rm, trim = trim)
}

mean3(x, , TRUE)
#> Error in `mean3()`:
#> ! Arguments in `...` must be used.
#> ✖ Problematic argument:
#> • ..1 = TRUE
#> ℹ Did you misspell an argument name?

mean3(x, n = TRUE, t = 0.1)
#> Error in `mean3()`:
#> ! Arguments in `...` must be used.
#> ✖ Problematic arguments:
#> • n = TRUE
#> • t = 0.1
#> ℹ Did you misspell an argument name?``````

• Chapter 21: if `…` is a required argument because it’s used to combine an arbitrary number of objects in a data structure.
• Chapter 23: to ensure that arguments to `…` never go silently missing.
2. Note that I moved `na.rm = TRUE` in front of `trim` because I believe `na.rm` is the more important argument because it’s used vastly more often than `trim` and I’m following Chapter 6.↩︎