[Rd] environment question

Simon Urbanek simon.urbanek at r-project.org
Sun May 18 06:02:37 CEST 2014

On May 17, 2014, at 7:26 PM, Mick Jordan <mick.jordan at oracle.com> wrote:

> On 5/17/14, 4:00 PM, peter dalgaard wrote:
>> On 17 May 2014, at 19:42 , Mick Jordan <mick.jordan at oracle.com> wrote:
>>> According to
>>> :https://stat.ethz.ch/R-manual/R-devel/library/base/html/environment.html
>>> "If |fun| is a function or a formula then |environment(fun)| returns the
>>> environment associated with that function or formula. If |fun| is |NULL|
>>> then the current evaluation environment is returned."
>>>> environment()
>>> <environment: R_GlobalEnv>
>>>> environment(environment)
>>> <environment: namespace:base>
>>> This makes sense, however I have two questions on things that don't seem
>>> to make sense:
>>> 1.
>>>> .Internal(environment(NULL))
>>> <environment: base>
>>> Since we are calling from R_GlobalEnv, how can the calling environment
>>> be base?
>> Read the Description section in ?.Internal carefully....
>> Basically, you are calling .Internal from the command line. It is not designed to be called from there and only wizards know what happens if it is. (The set of wizards who might know whether it makes any sense at all does not include me!)
> Well, calling from the shell. Anyway, I was just surprised by the result as, notwithstanding the fact that .Internal is "special", the calling environment is definitely .globalEnv. The enclosing environment might well be different, but that's not what environment(NULL) returns. My curiosity relates to the fact that the two calls have different stack depths, so that the .Internal(environment(NULL)) call has to detect whether it was called via environment() or .Internal(environment(NULL)) in order to return the right answer.

.Internal() doesn't setup a context for the evaluation environment so sysparent doesn't reflect the evaluation environment. That's why environment() only works when used as a closure, compare:

> environment()
<environment: R_GlobalEnv>
> .Internal(environment(NULL))
<environment: base>
> (function() .Internal(environment(NULL)))()
<environment: R_GlobalEnv>

Again, you have been warned not to call .Internal() unless you know what you're doing so you should know what is actually happening if you call it ;).

>>> 2.
>>> In eval.R in library/base/R:
>>> .GlobalEnv <- environment()
>>> parent.frame <- function(n = 1) .Internal(parent.frame(n))
>>> etc.
>>> Since the functions being defined are in base, how can the calling
>>> environment be R_GlobalEnv. Or does this just set .GlobalEnv temporarily
>>> to base?
>> .GlobalEnv is a variable in base alright. The assignment happens when base is being loaded and _at that point_ the environment is R_GlobalEnv.
> Sorry, I don't understand how that can be. The function definitions in, say, eval.R, and all the others in library/base/R, end up in base, as made clear by ls(baseenv()). So if these files are evaluated in the "usual way", and the environment() call in eval.R returns globalenv(), then they would, in fact, be defined there and not in baseenv. Now, I realise that this is startup code, so perhaps the implementation does something special and these files really aren't evaluated in the "usual" way.

More importantly that's not the value forever - note that later there is

.GlobalEnv <- globalenv()

in base/R/Rprofile which is loaded *after* base/R/*.R which is the value you see when you check after base is locked.


More information about the R-devel mailing list