Edit:
If you just want to check for duplicate arguments, you can do this:
any(duplicated(names(formals(ffoo))))
As Hadley mentions in his second comment below, dput() does not guarantee you a good / complete representation of the function, so there may be functions for which the approach described in my original answer (bottom left) fails.
Original answer:
As outlined in the C code that Andrie points to , this is apparently a test of what R does when parsing (not evaluating) call function() . This is why you were able to get around validation with your call to formals<- , and why the following (for example) also avoids validation. In both cases, the function is changed / created without parsing the call to function() .
eval(call("function", formals(ffoo), body(ffoo)))
The R parsing mechanism is usually not displayed in user-visible R-functions, so I would not assume that there is no ready-made R-function for this check. However, you can perform the same set of checks that R performs when you send an expression, or enter it on the command line, converting a function definition into its character representation, and then trying to reanalyze it yourself.
Here's a general idea:
parse(text = capture.output(dput(ffoo))) # Error in parse(text = capture.output(dput(ffoo))) : # repeated formal argument 'x' on line 1
To wrap the check as a function, do something like this:
isParseableFunction <- function(x) { tryCatch(is.function(x) & is.expression(parse(text = capture.output(dput(x)))), error = function(e) FALSE) } isParseableFunction(data.frame)
source share