From mick.jordan at oracle.com  Mon Mar 28 00:08:44 2016
From: mick.jordan at oracle.com (Mick Jordan)
Date: Sun, 27 Mar 2016 15:08:44 -0700
Subject: [Rd] sys.function(0)
In-Reply-To: <74C577BC-7127-4D7A-A839-0ADFBB569A30@gmail.com>
References: <56F83CF4.3050900@oracle.com>
	<74C577BC-7127-4D7A-A839-0ADFBB569A30@gmail.com>
Message-ID: <56F859EC.20602@oracle.com>

On 3/27/16 2:46 PM, peter dalgaard wrote:
>> On 27 Mar 2016, at 22:05 , Mick Jordan <mick.jordan at oracle.com> wrote:
>>
>> As I understand
>> https://stat.ethz.ch/R-manual/R-devel/library/base/html/sys.parent.html
>> sys.function(n) returns the function associated with stack frame n.
>> Since frame 0 is defined as .GlobalEnv which is not associated with a
>> function, I would expect this to always return NULL. However, it does not:
>>
>>> sys.function()
>> NULL
>>> f <- function(x) sys.function(x)
>>> f(0)
>> function(x) sys.function(x)
>>> f(1)
>> function(x) sys.function(x)
>>> f(2)
>> Error in sys.function(x) : not that many frames on the stack
>>
>> Why the different behavior when sys.function(0) is called inside another
>> function?
> This is a documentation bug. The case "which = 0" differs between sys.frame() and sys.call()/sys.function(). For the latter, it means the current call/function, whereas sys.frame(0) is always the global envir. It is pretty clear from the underlying C code that the three functions treat their argument differently:
>
> R_sysframe has
>
>      if (n == 0)
>          return(R_GlobalEnv);
>
>      if (n > 0)
>          n = framedepth(cptr) - n;
>      else
>          n = -n;
>
> whereas the other two (R_syscall and R_sysfunction) omit the special treatment for n==0. Without this, n==0, comes out unchanged from the if-construct, indicating that one should go 0 frames up the stack (same as n==framedepth(cptr)).
>
> Obviously, it won't work to document the "which" argument identically for all three functions...
>
>
Thanks. I didn't look at the C code this time trusting the documentation ;-)

A related question is why are sys.parent/parent.frame so permissive in 
their error checking? E.g:

 > sys.parent(-1)
[1] 0
 > sys.parent(-2)
[1] 0
 > sys.parent(1)
[1] 0
 > sys.parent(2)
[1] 0
 > parent.frame(4)
<environment: R_GlobalEnv>
 >



[Rd] sys.function(0)
Mick Jordan