To expand on @Pavel Obraztcov's excellent answer (and @James' comment above), take this function f
as an example:
f <- function(x) {
if(x == "foo") {
return("you said 'foo'")
} else if(x == "bar") {
return("you said 'bar'")
} else if(x == "xyz") {
stop("'xyz' is not a valid option")
}
}
(Not necessarily a good function, but there's nothing to stop someone from writing a function like this.)
How would we want to define "valid values" for the argument x
? We could say the valid values are foo
, bar
, and xyz
, since f
explicitly handles those three values. But it's clearly insufficient to just write a piece of code that parses a series of simple if-else statements; not all functions are structured this way.
And f
handles xyz
by throwing an error, so maybe only foo
and bar
are valid values? But in that case, we need a piece of code that will examine the internal logic of f
and determine that xyz
always leads to an error. That's not a trivial task - and I'm no CS expert, but it occurs to me to wonder whether the halting problem comes into play here.
Also, f
does nothing for values other than foo
, bar
, and xyz
- that's probably bad in this context, but are there contexts where both "return something" and "do nothing" would be acceptable ("valid") outcomes?
Things would be even worse if f
didn't handle x
directly, but instead passed it to some other function. Now we need to trace the internal logic of f
and any functions it calls.
So no, there's no general algorithmic way to get all valid options for some argument. When documentation and the internet fail, reading the source code (as a human) is the general way.
sub("geom_","",apropos("^geom_"))
– Newsprint