Reputation: 3229
I am learning about functions returning other functions. For example:
foo1 <- function()
{
bar1 <- function()
{
return(constant)
}
}
foo2 <- function()
{
constant <- 1
bar2 <- function()
{
return(constant)
}
}
Suppose, now, I declare functions f1
and f2
as follows:
constant <- 2
f1 <- foo1()
f2 <- foo2()
Then it appears they have the same function definition:
> f1
function()
{
return(constant)
}
<environment: 0x408f048>
> f2
function()
{
return(constant)
}
<environment: 0x4046d78>
>
BUT the two functions are different. For example:
> constant <- 2
> f1()
[1] 2
> f2()
[1] 1
My question: Why is it legal for two functions, with identical function definitions, to produce different results?
I understand that foo1
treats constant as a global variable and foo2
as a constant variable, but it is impossible to tell this from the function definition surely?
(I am probably missing something fundamental.)
Upvotes: 4
Views: 161
Reputation: 3008
Lev's answer is correct. To describe in more detail. When you you call f1 or pass f1 around you also have a reference to the original lexical environment in which the function was defined.
#since R is interpreted.. the variable constant doesn't have to be defined in the lexical environment... this all gets checked and evaluated at runtime
foo1ReturnedThisFunction <- foo1()
#outputs "Error in foo1ReturnedThisFunction() : object 'constant' not found"
foo1ReturnedThisFunction()
#defined the variable constant in the lexical environment
constant <- 5
#outputs 5
foo1ReturnedThisFunction()
in foo2... there is a definition of the variable constant in the "closer" (not sure if this is the right term) lexical environment so it uses that and doesn't look for the variable constant in the "global" environment
Upvotes: 2
Reputation: 3728
Sure they're different, the environments are different. Try ls(environment(f1))
and then ls(environment(f2))
and then get('constant', environment (f1))
and same for f2
Upvotes: 7