Greetings,
Say I have defined
mp <- function(a) function(x) x^a
f2 <- mp(2)
and I would like to retrieve the "a" which is local to f2. Two options
come to mind;
get("a", envir=environment(f2))
eval(substitute(a), environment(f2))
I'm curious if one of these is preferred over the other in terms of
efficiency, robustness, aesthetics, etc. Or perhaps someone can share
another way to skin this cat, besides wrappers around eval() like
evalq(a, environment(f2))
with(environment(f2), a)
Also, I'd like to confirm that I have used the correct terminology in
the subject line, that "a" is a local variable with respect to f2, which
is a closure?
Thanks,
Ben
best practice(s) for retrieving a local variable from a closure
6 messages · William Dunlap, Benjamin Tyner, Barry Rowlingson +1 more
On Fri, Apr 8, 2011 at 9:48 PM, Benjamin Tyner <btyner at gmail.com> wrote:
Greetings,
Say I have defined
?mp <- function(a) function(x) x^a
?f2 <- mp(2)
and I would like to retrieve the "a" which is local to f2. Two options come
to mind;
?get("a", envir=environment(f2))
?eval(substitute(a), environment(f2))
I'm curious if one of these is preferred over the other in terms of
efficiency, robustness, aesthetics, etc. Or perhaps someone can share
another way to skin this cat, besides wrappers around eval() like
?evalq(a, environment(f2))
?with(environment(f2), a)
Also, I'd like to confirm that I have used the correct terminology in the
subject line, that "a" is a local variable with respect to f2, which is a
closure?
Solutions involving eval tend to be less preferred. "a" is termed a free variable of f2.
Statistics & Software Consulting GKX Group, GKX Associates Inc. tel: 1-877-GKX-GROUP email: ggrothendieck at gmail.com
-----Original Message-----
From: r-help-bounces at r-project.org
[mailto:r-help-bounces at r-project.org] On Behalf Of Benjamin Tyner
Sent: Friday, April 08, 2011 6:48 PM
To: r-help at r-project.org
Subject: [R] best practice(s) for retrieving a local variable
from a closure
Greetings,
Say I have defined
mp <- function(a) function(x) x^a
f2 <- mp(2)
and I would like to retrieve the "a" which is local to f2.
Two options
come to mind;
get("a", envir=environment(f2))
eval(substitute(a), environment(f2))
I'm curious if one of these is preferred over the other in terms of
efficiency, robustness, aesthetics, etc. Or perhaps someone can share
another way to skin this cat, besides wrappers around eval() like
evalq(a, environment(f2))
with(environment(f2), a)
You can also use a list-like notation with environments:
> environment(f2)$a
[1] 2
> environment(f2)[["a"]]
[1] 2
> environment(f2)$a <- 3:1
> f2(2)
[1] 8 4 2
The above feels a bit like snooping where I wasn't invited.
You could do something like
mq <- function(a) {
force(a)
list(getA = function()a,
setA = function(newA) a <<- newA,
fun = function(x)x^a
)
}
to make it clear that you expect people to look at or change
fun's 'a'.
> f3 <- mq(3)
> f3$fun(5)
[1] 125
> f3$getA()
[1] 3
> f3$setA(4:1)
> f3$fun(3)
[1] 81 27 9 3
I don't code like this much so haven't developed a sense of
aesthetics about these variants.
Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com
Also, I'd like to confirm that I have used the correct terminology in the subject line, that "a" is a local variable with respect to f2, which is a closure? Thanks, Ben
Thanks Bill and Gabor!
William Dunlap wrote:
-----Original Message-----
From: r-help-bounces at r-project.org
[mailto:r-help-bounces at r-project.org] On Behalf Of Benjamin Tyner
Sent: Friday, April 08, 2011 6:48 PM
To: r-help at r-project.org
Subject: [R] best practice(s) for retrieving a local variable
from a closure
Greetings,
Say I have defined
mp <- function(a) function(x) x^a
f2 <- mp(2)
and I would like to retrieve the "a" which is local to f2.
Two options
come to mind;
get("a", envir=environment(f2))
eval(substitute(a), environment(f2))
I'm curious if one of these is preferred over the other in terms of
efficiency, robustness, aesthetics, etc. Or perhaps someone can share
another way to skin this cat, besides wrappers around eval() like
evalq(a, environment(f2))
with(environment(f2), a)
You can also use a list-like notation with environments:
> environment(f2)$a
[1] 2
> environment(f2)[["a"]]
[1] 2
> environment(f2)$a <- 3:1 > f2(2)
[1] 8 4 2
The above feels a bit like snooping where I wasn't invited.
You could do something like
mq <- function(a) {
force(a)
list(getA = function()a,
setA = function(newA) a <<- newA,
fun = function(x)x^a
)
}
to make it clear that you expect people to look at or change
fun's 'a'.
> f3 <- mq(3) > f3$fun(5)
[1] 125
> f3$getA()
[1] 3
> f3$setA(4:1) > f3$fun(3)
[1] 81 27 9 3 I don't code like this much so haven't developed a sense of aesthetics about these variants. Bill Dunlap Spotfire, TIBCO Software wdunlap tibco.com
Also, I'd like to confirm that I have used the correct terminology in the subject line, that "a" is a local variable with respect to f2, which is a closure? Thanks, Ben
On Sat, Apr 9, 2011 at 6:29 PM, Benjamin Tyner <btyner at gmail.com> wrote:
The above feels a bit like snooping where I wasn't invited.
You could do something like
?mq <- function(a) {
? ? force(a)
? ? list(getA = function()a,
? ? ? ? ?setA = function(newA) a <<- newA,
? ? ? ? ?fun = function(x)x^a
? ? )
?}
to make it clear that you expect people to look at or change
fun's 'a'.
Once you start doing a lot of that though you may as well go the whole OO hog and use the proto or R.oo packages... Barry
On Sat, Apr 9, 2011 at 3:27 PM, Barry Rowlingson
<b.rowlingson at lancaster.ac.uk> wrote:
On Sat, Apr 9, 2011 at 6:29 PM, Benjamin Tyner <btyner at gmail.com> wrote:
The above feels a bit like snooping where I wasn't invited.
You could do something like
?mq <- function(a) {
? ? force(a)
? ? list(getA = function()a,
? ? ? ? ?setA = function(newA) a <<- newA,
? ? ? ? ?fun = function(x)x^a
? ? )
?}
to make it clear that you expect people to look at or change
fun's 'a'.
?Once you start doing a lot of that though you may as well go the whole OO hog and use the proto or R.oo packages... Barry
In the case of proto it would be this: library(proto) mq <- proto(fun = function(., x) x^.$a) mq$a <- 2 mq$a # 2 mq$fun(3) # 9 or you could make explicit getter and setter functions though, as seen, they are not really needed: mq <- proto(fun = function(., x) x^.$a, getA = function(.) .$a, setA = function(., a) .$a <- a) mq$setA(3) mq$getA() # 3 mq$fun(4) # 64
Statistics & Software Consulting GKX Group, GKX Associates Inc. tel: 1-877-GKX-GROUP email: ggrothendieck at gmail.com