[R] environments and lexical scoping (conceptual issues)

Thomas Lumley thomas at biostat.washington.edu
Fri May 19 03:31:29 CEST 2000


On Thu, 18 May 2000, Faheem Mitha wrote:

> 
> VR> The enclosing environment need not be the parent environment, the 
> VR> environment from which the evaluation environment was created, and
> VR> [the enclosing environment (my addition)] is usually the environment
> VR> within which the function was created, often the workspace.
> 
> ?? I don't understand. If "the enclosing environment need not be the
> parent environment, from which the evaluation environment was created"
> then this seems to contradict the previous para, where it says "When the
> evaluation environment is a function body, the enclosing environment is
> that of the function, which is normally the environment within which the
> function was defined." Does the last para refer to situations other than
> functions defined within functions? If so, an example of this would be
> helpful in understanding what is meant. And if the enclosing environment
> is not the parent environment, then how is the enclosing environment
> chosen? 

There are two environments: the one that the function was defined in
("enclosing"), and the one it was invoked in ("parent")

If you create a function at the command line or load it in a package it's
enclosing environment is the global workspace.   If you define a function
f() inside another function g() its enclosing environment
is the environment inside g(). The enclosing environment for a function is
fixed when the function is created.  You can find out the enclosing
environment for a function f() using 
	environment(f)

The "parent" environment, on the other hand, is defined when you invoke a
function.  If you invoke lm() at the command line its parent environment
is the global workspace, if you invoke it inside a function f() then its
parent environment is the environment inside f().  You can find out the
parent environment for an invocation of a function by using
sys.frame(sys.parent()).


So for most user-visible functions the enclosing environment will be the
global workspace, since that is where most functions are defined.  The
parent environment will be wherever the function happens to be called
from.

If a function f() is defined inside another function g() it will probably
be used inside g() as well, so in fact its parent environment and
enclosing environment will be the same.


Parent environments are important is that things like model formulas need
to be evaluated in the environment the function was called from, since
that's where all the variables will be available. This relies on the
parent environment being potentially different with each invocation.

Enclosing environments are important because a function can use variables
in the enclosing environment to share information with other functions or
with other invocations of itself. This relies on the enclosing environment
being the same each time the function is invoked.

Scoping *is* hard.  Looking at examples helps, and I would particularly
recommend playing around with all the examples in that chapter of VR. It
is particularly instructive to look at examples that work differently in
R and S and try to see why they differ.

	-thomas

Thomas Lumley
Assistant Professor, Biostatistics
University of Washington, Seattle

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._



More information about the R-help mailing list