From murdoch at stats.uwo.ca  Thu Oct 26 06:11:13 2006
From: murdoch at stats.uwo.ca (Duncan Murdoch)
Date: Thu, 26 Oct 2006 00:11:13 -0400
Subject: [Rd] how to determine if a function's result is invisible
In-Reply-To: <971536df0610252002s46ef72b2n32df3e180a49e990@mail.gmail.com>
References: <971536df0610251714u451cf80fy80bf38cb2f130734@mail.gmail.com>	
	<454023EA.4020403@stats.uwo.ca>
	<971536df0610252002s46ef72b2n32df3e180a49e990@mail.gmail.com>
Message-ID: <45403561.1000808@stats.uwo.ca>

On 10/25/2006 11:02 PM, Gabor Grothendieck wrote:
> On 10/25/06, Duncan Murdoch <murdoch at stats.uwo.ca> wrote:
>> On 10/25/2006 8:14 PM, 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)
>> I don't think there's a way to do that.  Internally there's a global
>> flag called R_Visible; if it is set to zero, the value won't print.  But
>>  it gets reset to 1 very easily (e.g. by adding 1 to the result of an
>> invisible function), and it's not available in the API for you to write
>> C code to look at it.
>>
>> I think you'll just have to do require the user of your F to tell you
>> that they want the result to be invisible.
>>
>> Duncan Murdoch
>>
> 
> Perhaps R_Visible be made available at the R level in the future.
> It would be helpful in situations where you are transforming a
> function but want to keep aspects of it such as whether the
> return result is invisible.

Actually, there is a way, but it's undocumented (i.e., use at your own 
risk).  It's the eval.with.vis function.  This is an internal function 
that is used within source() and capture.output(); you'll have to guess 
from the usage there what the args are.   But here's an F that does 
something close to what you want:

 > fix(F)
 > f <- function() 1
 > g <- function() invisible(1)
 >
 > F <- function (expr)
+ {
+     expr <- substitute(expr)
+     pf <- parent.frame()
+     tmp <- .Internal(eval.with.vis(expr, pf,
+         baseenv()))
+     tmp
+ }
 > F(f())
$value
[1] 1

$visible
[1] TRUE

 > F(g())
$value
[1] 1

$visible
[1] FALSE




[Rd] how to determine if a function's result is invisible
Duncan Murdoch