From m@ech|er @end|ng |rom @t@t@m@th@ethz@ch  Thu Mar 28 12:42:49 2019
From: m@ech|er @end|ng |rom @t@t@m@th@ethz@ch (Martin Maechler)
Date: Thu, 28 Mar 2019 12:42:49 +0100
Subject: [Rd] topenv of emptyenv
In-Reply-To: <CAM2gKPaSjQp3Eq4Gy+B7RO-LgwgUoo8RV3JrA452f2v2FZAgLg@mail.gmail.com>
References: <CAM2gKPaSjQp3Eq4Gy+B7RO-LgwgUoo8RV3JrA452f2v2FZAgLg@mail.gmail.com>
Message-ID: <23708.45881.551325.849739@stat.math.ethz.ch>

>>>>> Konrad Rudolph 
>>>>>     on Sat, 23 Mar 2019 14:26:40 +0000 writes:
>>>>> Konrad Rudolph 
>>>>>     on Sat, 23 Mar 2019 14:26:40 +0000 writes:

    > I was surprised just now to find out that `topenv(emptyenv())` equals
    > ? `.GlobalEnv`, not `emptyenv()`. From my understanding of the
    > description of `topenv`, it should walk up the chain of enclosing
    > environments (as if by calling `e = parent.env(e)` repeatedly; in
    > fact, that is almost exactly its implementation in envir.c) until it
    > hits a top level. However, `emptyenv()` has no enclosing environments
    > so it should be its own top-level environment (I thought).
    > Unfortunately the documentation on environments is relatively sparse,
    > and the R Internals document doesn?t mention top-level environments.

    > Concretely, I encountered this in the following code, which signals an
    > error if `env` is the empty environment:

    > while (! some_complex_condition(env) && ! identical(env, toplevel(env))) {
    > 	    env = parent.env(env)
    > }

I guess the above 'toplevel(env)' should be replaced by 'topenv(env)' ?

    > Of course there?s a trivial workaround (add an identity check for
    > `emptyenv()` in the while loop condition) but it got me wondering if
    > there?s a rationale for this result or if it?s ?accidental?/arbitrary:
    > the C `topenv` implementation defaults to returning R_GlobalEnv for an
    > empty environment. Is this effect actually useful (and used anywhere)?

I don't know if it's useful or used anywhere.
I've not seen topenv() used a lot at all ...  contrary to parent.env(),
and as we know,

  > parent.env(emptyenv())
  Error in parent.env(emptyenv()) : the empty environment has no parent

very much on purpose.

Note that you should not directly be surprised.  If you were you
did not read   ?topenv  carefully enough:

It says that the value returned must be "top level environment" (=: TLE)
and then defines TLE as

>  An environment is considered top level if it is the internal environment of a
>  namespace, a package environment in the search path, or .GlobalEnv .

So from that definition it must return .Globalenv in this
particular case.

On the other hand, if you want a test of

   identical(env, topenv(env))

to make sense I understand that you'd want to allow  topenv() to
return emptyenv() in your case, i.e., you'd want the above
identical(..) to be true in this case...

Still, with the definition of  TLE  as it has been on the help
page forever,  emptyenv() really does not belong

    > This is in R 3.4.4 but I can?t find an indication that this behaviour
    > was ever changed.

Indeed... and as I mentioned I had never actively noticed the
use of topenv() at all...

Martin


    > Cheers

    > -- 
    > Konrad Rudolph

    > ______________________________________________
    > R-devel at r-project.org mailing list
    > https://stat.ethz.ch/mailman/listinfo/r-devel



[Rd] topenv of emptyenv
Martin Maechler