There are three main methods by which arguments are matched. These are discussed in the Argument Matching section of the R Language Definition, the relevant section of which I reproduce below:
The first thing that occurs in a function evaluation is the matching
of formal to the actual or supplied arguments. This is done by a
three-pass process:
- Exact matching on tags. For each named supplied argument the list of formal arguments is searched for an item whose name matches
exactly. It is an error to have the same formal argument match several
actuals or vice versa.
- Partial matching on tags. Each remaining named supplied argument is compared to the remaining formal arguments using partial matching.
If the name of the supplied argument matches exactly with the first
part of a formal argument then the two arguments are considered to be
matched. It is an error to have multiple partial matches. Notice that
if
f <- function(fumble, fooey) fbody
, then f(f = 1, fo = 2)
is
illegal, even though the 2nd actual argument only matches fooey
.
f(f = 1, fooey = 2)
is legal though since the second argument
matches exactly and is removed from consideration for partial
matching. If the formal arguments contain ...
then partial matching
is only applied to arguments that precede it.
- Positional matching. Any unmatched formal arguments are bound to unnamed supplied arguments, in order. If there is a
...
argument, it
will take up the remaining arguments, tagged or not.
Note that this is what happens with normal functions. Primitve functions are special in R. Primitives are special in many ways and invariably don't use tags but use positional matching instead. This is not consistently applied however.
Another important exception is arguments in functions that include a ...
argument. As mentioned above, if an argument occurs after ...
in the argument list of a function, you must name that argument in a call to that function if as positional matching is not applied to these arguments. For example:
foo <- function(x, ..., y) {
y
}
The only way to pass a value to y
is to name it in the function call, e.g.:
foo(y = 1)