how to determine if a function's result is invisible
On 10/25/06, Marc Schwartz <MSchwartz at mn.rr.com> wrote:
On Wed, 2006-10-25 at 19:16 -0700, Deepayan Sarkar wrote:
On 10/25/06, Marc Schwartz <MSchwartz at mn.rr.com> wrote:
On Wed, 2006-10-25 at 20:14 -0400, Gabor Grothendieck wrote:
Suppose we have a function such as the following F <- function(f, x) f(x)+1 which runs function f and then transforms it. I would like the corresponding function which works the same except that unlike F returns an invisible result if and only if f does. Is there some way of determining whether f returns an invisible result or not? Thus we want this: f <- function(x) x g <- function(x) invisible(x)
F(f, 1)
2
F(g, 1)
Gabor,
There may be a better way of doing this and/or this will spark some
thoughts.
Let's create two simple functions:
f.inv <- function(x) {invisible(x)}
f <- function(x) {x}
So we now have:
f.inv(1) f(1)
[1] 1
any(grep("invisible", (deparse(f))))
[1] FALSE
any(grep("invisible", (deparse(f.inv))))
[1] TRUE
That's not going to work, since invisibility can also be a side effect
of assignment, e.g.
g <- function(x) { x <- x }
Good point. Can we tweak it a bit to try to cover additional
situations, such as this? For example:
is.invisible <- function(x)
{
dep.x <- deparse(x)
ifelse(any(grep("invisible", dep.x)) |
any(grep("<-", dep.x[length(dep.x) - 1])),
TRUE, FALSE)
}
f.inv <- function(x) {invisible(x)}
f <- function(x) {x}
g <- function(x) { x <- x }
is.invisible(f.inv)
[1] TRUE
is.invisible(f)
[1] FALSE
is.invisible(g)
[1] TRUE
In this case to (possibly) cover the assignment situation, I am looking
for an assignment operator ("<-") in the last code line of the function
body. Note that if there are blank lines in the function body after the
assignment line and before the closing brace, the assignment line is
still the final line of code found in the deparse().
Given Duncan's comment, it sounds like this might not be doable for 100%
of the situations, but we may be able to cover the 80% of the common
ones.
Gabor, to your follow up comment about generics, perhaps the code can be
yet further extended to check the class of the relevant argument(s) to
the function(s) in question to similarly search/deparse the methods that
would presumably be dispatched. It would certainly become more
convoluted however.
In the case of S3 one could search for a UseMethod and, if found, just search all available methods for invisible without trying to figure out which one(s) get dispatched on the theory that its likely that they will all return or all not return invisibly since methods are supposed to maintain a certain sense of semantic consistency. In the case of internal R functions there may not be that many that return invisibly so one could just make a list of them and check against that list. Is there some way to grep these out?