Peter Dalgaard wrote: > > <..snip> > Checking... Yep, the logic in R_sysfunction() is to give the function > of frame #n: > > if (n > 0) > n = framedepth(cptr) - n; > else > n = - n; > if (n < 0 ) > errorcall(R_GlobalContext->call, "illegal frame number"); > while (cptr->nextcontext != NULL) { > if (cptr->callflag & CTXT_FUNCTION ) { > if (n == 0) > return duplicate(cptr->callfun); /***** do we need to DUP? */ > else > n--; > } > cptr = cptr->nextcontext; > } > > whereas the documentation has > > 'sys.function' gives the definition of the function currently > being evaluated in the frame 'n' generations back. > > However, we're using the current convention in quite a few places > (sys.function(sys.parent())) and, worse, who know what packages might > do. It is tempting just to change the documentation, but it is part of > a grouped documentation of sys.whatever, which has > > which: the frame number if non-negative, the number of generations > to go back if negative. (See the Details section.) > > n: the number of frame generations to go back. > > and sys.function is documented with argument 'n', which we'd have to > change to 'which', but the default is n=0 for "current function" which > is unlike 'which' which has 0 meaning .GlobalEnv. Argh... > > My take is that we need to fix sys.function to behave according to > docs, change what we can in the R internals, and face the consequences > for package maintainers.
Things are actually messier, even. 1. A counter-argument for changing the documentation might be that the green book (p 106) and S-Plus take the argument to be the frame number (only sys.parent(n) uses the argument for the number of frames back). Unfortunately for the counter-argument, the (current) R implementation and the S-Plus implementation differ in where they start indexing. In S-Plus, 1 is the top-level frame (corresponding to the global environment). In R, it is the first function call frame (and 0 corresponds to the global environment). So there seems no way to have R/S-Plus compatibility. 2. And R-only consistency does not look too good either: sys.call() and sys.frame() claim to have the which= behavior. It's not very natural for sys.function() to behave differently. And even if that didn't bother us, sys.call(0) returns the current call, not the "global call" (whatever that would mean), regardless of documentation. (The test at the bottom of this mail illustrates.) What to do? Well, a tentative suggestion. - Leave the implementation almost alone--no simple fix will clean up all the problems. Optionally make one change: If sys.frame(0) produced the frame of the current call, then sys.function, sys.call, and sys.frame would be consistent. - Change the documentation to give sys.function argument `which', explaining that which=0 is interpreted as the current call/function/frame. If we wanted to leave the implementation totally unchanged, then we have to admit the inconsistency in sys.frame, and tell people to use sys.frame(sys.nframe()) to produce the current frame. John > > -- > O__ ---- Peter Dalgaard Blegdamsvej 3 > c/ /'_ --- Dept. of Biostatistics 2200 Cph. N > (*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918 > ~~~~~~~~~~ - ([EMAIL PROTECTED]) FAX: (+45) 35327907 > > ______________________________________________ > [EMAIL PROTECTED] mailing list > https://www.stat.math.ethz.ch/mailman/listinfo/r-devel -- John M. Chambers [EMAIL PROTECTED] Bell Labs, Lucent Technologies office: (908)582-2681 700 Mountain Avenue, Room 2C-282 fax: (908)582-3340 Murray Hill, NJ 07974 web: http://www.cs.bell-labs.com/~jmc -------------------------------------------------------------------- Example. Source in the following function definitions: foo <- function(n)bar(n) bar <- function(n)baz(n) baz <- function(n)list(sys.function(n), sys.call(n), sys.frame(n)) Call foo() with various arguments. In R, you get: R> foo(1) [[1]] function(n)bar(n) [[2]] foo(1) [[3]] <environment: 0x8eb6378> R> foo(2) [[1]] function(n)baz(n) [[2]] bar(n) [[3]] <environment: 0x8eb6d24> R> foo(3) [[1]] function(n)list(sys.function(n), sys.call(n), sys.frame(n)) [[2]] baz(n) [[3]] <environment: 0x8eb7e68> R> foo(0) [[1]] function(n)list(sys.function(n), sys.call(n), sys.frame(n)) [[2]] baz(n) [[3]] <environment: R_GlobalEnv> ----------------------------------- In S-Plus you get: S+> foo(1) [[1]]: NULL [[2]]: [[2]]$.Last.expr: expression(foo(1)) [[2]]$.Auto.print: [1] T S+> foo(2) [[1]]: function(n) bar(n) [[2]]: foo(2) [[3]]: [[3]]$n: [1] 2 S+> foo(3) [[1]]: function(n) baz(n) [[2]]: bar(n) [[3]]: [[3]]$n: [1] 3 S+> foo(0) Problem in sys.function(n): Illegal frame number (0), should be between 1 and 5 Debug ? ( y|n ): n ______________________________________________ [EMAIL PROTECTED] mailing list https://www.stat.math.ethz.ch/mailman/listinfo/r-devel