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? Mick Jordan
sys.function(0)
4 messages · Mick Jordan, Peter Dalgaard
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...
-pd
Mick Jordan [[alternative HTML version deleted]]
______________________________________________ R-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Peter Dalgaard, Professor, Center for Statistics, Copenhagen Business School Solbjerg Plads 3, 2000 Frederiksberg, Denmark Phone: (+45)38153501 Office: A 4.23 Email: pd.mes at cbs.dk Priv: PDalgd at gmail.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> >
Dunno, really. Some strange things can happen with nonstandard evaluation, like having a function designed to evaluate something in the parent of its caller, but nonetheless sometimes being called from the command line. So things are sometimes defensively coded. -pd
On 28 Mar 2016, at 00:08 , Mick Jordan <mick.jordan at oracle.com> wrote: 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>
Peter Dalgaard, Professor, Center for Statistics, Copenhagen Business School Solbjerg Plads 3, 2000 Frederiksberg, Denmark Phone: (+45)38153501 Office: A 4.23 Email: pd.mes at cbs.dk Priv: PDalgd at gmail.com