The symbols which occur in the body of a function can be divided into three classes; formal parameters, local variables and free variables. The formal parameters of a function are those occurring in the argument list of the function. Their values are determined by the process of binding the actual function arguments to the formal parameters. Local variables are those whose values are determined by the evaluation of expressions in the body of the functions. Variables which are not formal parameters or local variables are called free variables. Free variables become local variables if they are assigned to. Consider the following function definition.
f<-function(x) {
y<-2*x
print(x)
print(y)
print(z)
}
In this function x is a formal parameter, y is a local variable
and z is a free variable.
In . the free variable bindings are resolved by first looking
in the environment in which the function was created.
First we define a function called cube.
cube<-function(n){
sq<-function() n*n
n*sq()
}
The variable n in the function sq is not an
argument to that function.
Therefore it is a free variable and the scoping rules must be used to
ascertain the value that is to be associated with it.
Under static scope the value is that associated with a global variable
named n.
Under lexical scope it is the parameter to the function cube since that
is the active binding for the variable n at the time the
function sq was defined.
The difference between evaluation in . and evaluation in . is that
. looks for a global variable called n while . first looks for a
variable called n in the environment created when cube was
invoked.
#first evaluation in S S> cube(2) Error in sq(): Object "n" not found Dumped S> n<-3 S> cube(2) [1] 18 #then the same function evaluated in R R> cube(2) [1] 8
Lexical scope can also be used to give functions mutable state. In the following example we show how . can be used to mimic a bank account. A functioning bank account needs to have a balance or total, a function for making withdrawals, a function for making deposits and a function for stating the current balance. We achieve this by creating the three functions within account and then returning a list containing them. When account is invoked it takes a numerical argument total and returns a list containing the three functions. Because these functions are defined in an environment which contains total, they will have access to its value.
The special assignment operator, <<-, is used to change the value
associated with total.
This operator looks back in enclosing environments for an environment
that contains the symbol total and when it finds such an environment
it replaces the value, in that environment, with the value of right hand
side.
If the global or top-level environment is reached without finding the
symbol total then that variable is created and assigned to there.
For most users <<- creates a global variable and
assigns the value of the right hand side to it
.
Only when <<- has been used in a function that was
returned as the value of another function will the special behaviour described
here occur.