Skip to content

lexical scope

5 messages · robin hankin, Laurent Gautier, Ramon Diaz-Uriarte +2 more

#
Hi everyone

another documented feature that was a bit unexpected for me:

R> x <- 19
R> f <- function(t){t+x}
R> f(100)
[1] 119

--as expected: x is visible from within f()
..but...


R> g <- function(a){x <- 1e99 ; return(f(a))}
R> g(4)
[1] 23

--the "x" that is visible from within g() is just 19, which is not the
  one I expected it to find.


R> rm(x)
R> g(4)
Error in f(a) : Object "x" not found

--g() looks in the first search path place and finds it empty,
  returning an error.


QUESTIONS:
Why doesn't g()  "keep looking" ?
How do I tell g() where to find x?
Where to look for documentation for this?
#
On Tue, Apr 22, 2003 at 04:07:39PM +1200, Robin Hankin wrote:
(TENTATIVE) ANSWERS:

1- becase the enclosing frame for f is .GlobalEnv.
2- f <- function(t){t+get("x", envir=parent.frame())}
3- R language definition p.22 is a place to start


Hopin' it helps,




L.

  
    
#
Dear Robin,

In terms of documentation I have found John Fox's "Frames, environments, and 
scope in R and S-PLUS" (available at
http://socserv.socsci.mcmaster.ca/jfox/Books/companion/appendix-scope.pdf) to 
be an excellent document. 

"Lexical scope and statistical computing" by Gentleman & Ihaka (at the J. 
Comp. Graph. Stat., 2000, 9: 491-508, though I think a pdf of a preprint can 
be found somewhere in the net) contains more general discussion and more 
ellaborate examples.

Finally, section 10.7 of "An introduction to R" has brief discussion of these 
issues, but that should answer the specific questions you asked.


With regards to your specific situation:
x is a "free variable" for f, and f will look for it in (at? I'll never get 
this right) the environment where it was defined (the global environment in 
your example).

When you call f from g, f still looks for x in the environment where it was 
defined; first time (before you rm(x)) x is 19 there; the second time, there 
is no x anymore.

This behavior is different from that of S-PLUS.

Hope this helps,

Ram?n
On Tuesday 22 April 2003 06:07, Robin Hankin wrote:

  
    
#
On Tue, 22 Apr 2003, Laurent Gautier wrote:

            
Yes. R has lexical, not dynamic, scope.  That is, the lookup depends on
where a function was defined, not where it was called from.

If you need to fake dynamic scope then
a) Try not to
b) Use eval.parent()

	-thomas
#
Dear Robin,
A couple of people have pointed out that the source of the difficulty here 
is lexical scoping. One can sometimes take advantage of lexical scoping by 
defining a local function. For your illustration, for example,

 > x <- 19
 > g <- function(a){
+     f <- function(t){t + x}
+     x <- 1e99
+     f(a)
+     }
 > g(4)
[1] 1e+99
 >

Whether or not this solves your problem depends upon whether it's 
reasonable to make f local to g.

John


-----------------------------------------------------
John Fox
Department of Sociology
McMaster University
Hamilton, Ontario, Canada L8S 4M4
email: jfox at mcmaster.ca
phone: 905-525-9140x23604
web: www.socsci.mcmaster.ca/jfox