Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New linter for unnamed arguments combined with ... #2627

Open
teunbrand opened this issue Jul 10, 2024 · 1 comment
Open

New linter for unnamed arguments combined with ... #2627

teunbrand opened this issue Jul 10, 2024 · 1 comment

Comments

@teunbrand
Copy link

teunbrand commented Jul 10, 2024

I thought it might be handy to have a linter that checks for the pattern fun(x, y, ...) where x and y are unnamed arguments and are matched to fun() based on their position. This is risky to combine with ... as a named argument in ... might supplant x or y and shift subsequent arguments.

To illustrate, this piece of code with named arguments correctly gives the 'matched by multiple arguments' error:

inner <- function(str, num, lgl) {
  stopifnot(is.character(str), is.numeric(num), is.logical(lgl))
  "succes"
}

outer <- function(...) inner(str = "a", num = 4, ...)

outer(TRUE)
#> [1] "succes"
outer(num = 5)
#> Error in inner(str = "a", num = 4, ...): formal argument "num" matched by multiple actual arguments

However, if we don't use named arguments we get into the following trouble. Note that num = 5 is passed through ... which means that the 2nd default argument (4) that is supposed to be the num argument is now shifted to the lgl argument.

outer <- function(...) inner("a", 4, ...)

outer(TRUE)
#> [1] "succes"
outer(num = 5)
#> Error in inner("a", 4, ...): is.logical(lgl) is not TRUE

Created on 2024-07-10 with reprex v2.1.0

For this reason, I think it'd be good to recommend naming arguments when combined with ....

@MichaelChirico
Copy link
Collaborator

Agree it's a good idea for a linter, but will be ~relatively tough to implement -- really it's something {codetools} is best suited for since it requires a strong sense of scope to get match.fun() working with sufficient accuracy to be useful (I reckon). Then like object_usage_linter() we'd pull out info from the codetools report.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants