Jeff Ryan
2013-Jan-01 21:35 UTC
[Rd] Behavior or as.environment in function arguments/call (and force() behaviors...)
Happy 2013!
Can someone with more knowledge of edge case scoping/eval rules explain
what is happening below? Happens in all the versions of R I have on hand.
Behavior itself is confusing, but ?as.environment also provides no clue.
The term used in that doc is 'search list', which is ambiguous, but the
see also section mentions search(), so I would *think* that is what is
intended. Either way Fn1() below can't really be explained.
Major question is what in the world is Fn1 doing, and why is Fn2 not equal
to Fn3? [ Fn3/Fn4 are doing what I want. ]
Fn1 <- function(x="test",pos=-1,env=as.environment(pos)) {
ls(env)
}
Fn2 <- function(x="test",pos=-1,env=as.environment(pos)) {
force(env)
ls(env)
}
Fn3 <- function(x="test",pos=-1,env=as.environment(pos)) {
# should be the same as force() in Fn2, but not
# ?force
# Note:
#
# This is semantic sugar: just evaluating the symbol will do the
# same thing (see the examples).
env
ls(env)
}
Fn4 <- function(x="test",pos=-1,env=as.environment(pos)) {
# same as Fn3
env <- env
ls(env)
}
Fn1()
Fn2()
Fn3()
Fn4()
ls()
###################### output #########################> Fn1()
[1] "doTryCatch" "expr" "handler"
"name" "parentenv"
> Fn2()
[1] "env" "pos" "x"
> Fn3()
[1] "Fn1" "Fn2" "Fn3" "Fn4"
> Fn4()
[1] "Fn1" "Fn2" "Fn3" "Fn4"
### .GlobalEnv> ls()
[1] "Fn1" "Fn2" "Fn3" "Fn4"
> R.version
_
platform x86_64-apple-darwin11.2.0
arch x86_64
os darwin11.2.0
system x86_64, darwin11.2.0
status
major 2
minor 15.1
year 2012
month 06
day 22
svn rev 59600
language R
version.string R version 2.15.1 (2012-06-22)
nickname Roasted Marshmallows
> R.version
_
platform x86_64-apple-darwin11.2.0
arch x86_64
os darwin11.2.0
system x86_64, darwin11.2.0
status Under development (unstable)
major 3
minor 0.0
year 2012
month 12
day 28
svn rev 61464
language R
version.string R Under development (unstable) (2012-12-28 r61464)
nickname Unsuffered Consequences
--
Jeffrey Ryan
jeffrey.ryan@lemnica.com
www.lemnica.com
[[alternative HTML version deleted]]
Duncan Murdoch
2013-Jan-01 22:21 UTC
[Rd] Behavior or as.environment in function arguments/call (and force() behaviors...)
On 13-01-01 4:35 PM, Jeff Ryan wrote:> Happy 2013! > > Can someone with more knowledge of edge case scoping/eval rules explain > what is happening below? Happens in all the versions of R I have on hand.Even though it is used as a default in a number of places, the pos==-1 value is really poorly documented. You need to look in the source, in particular src/main/envir.c, function pos2env. There you'll see that pos==-1 is special cased to be the environment from which pos.to.env (or as.environment in your case) was called. For non-negative values, it indexes the search list (i.e. the list returned by search().) Other values are errors. The trouble in your examples is that this location varies. In Fn1, it is being called in the ls() call. In Fn2, it is in the force() call. In Fn3 and Fn4, it's the Fn3/Fn4 call. In spite of what the docs say in ?get, I would rarely if ever use a pos argument to as.environment. Use an environment and pass it as envir. Duncan Murdoch> > Behavior itself is confusing, but ?as.environment also provides no clue. > The term used in that doc is 'search list', which is ambiguous, but the > see also section mentions search(), so I would *think* that is what is > intended. Either way Fn1() below can't really be explained. > > Major question is what in the world is Fn1 doing, and why is Fn2 not equal > to Fn3? [ Fn3/Fn4 are doing what I want. ] > > > Fn1 <- function(x="test",pos=-1,env=as.environment(pos)) { > ls(env) > } > > Fn2 <- function(x="test",pos=-1,env=as.environment(pos)) { > force(env) > ls(env) > } > > Fn3 <- function(x="test",pos=-1,env=as.environment(pos)) { > # should be the same as force() in Fn2, but not > # ?force > # Note: > # > # This is semantic sugar: just evaluating the symbol will do the > # same thing (see the examples). > env > ls(env) > } > > Fn4 <- function(x="test",pos=-1,env=as.environment(pos)) { > # same as Fn3 > env <- env > ls(env) > } > > Fn1() > Fn2() > Fn3() > Fn4() > ls() > > ###################### output ######################### >> Fn1() > [1] "doTryCatch" "expr" "handler" "name" "parentenv" > >> Fn2() > [1] "env" "pos" "x" > >> Fn3() > [1] "Fn1" "Fn2" "Fn3" "Fn4" > >> Fn4() > [1] "Fn1" "Fn2" "Fn3" "Fn4" > > ### .GlobalEnv >> ls() > [1] "Fn1" "Fn2" "Fn3" "Fn4" > >> R.version > _ > platform x86_64-apple-darwin11.2.0 > arch x86_64 > os darwin11.2.0 > system x86_64, darwin11.2.0 > status > major 2 > minor 15.1 > year 2012 > month 06 > day 22 > svn rev 59600 > language R > version.string R version 2.15.1 (2012-06-22) > nickname Roasted Marshmallows > >> R.version > _ > platform x86_64-apple-darwin11.2.0 > arch x86_64 > os darwin11.2.0 > system x86_64, darwin11.2.0 > status Under development (unstable) > major 3 > minor 0.0 > year 2012 > month 12 > day 28 > svn rev 61464 > language R > version.string R Under development (unstable) (2012-12-28 r61464) > nickname Unsuffered Consequences >
Possibly Parallel Threads
- [LLVMdev] Proposal : Function Notes
- [RFC][InlineCost] Modeling JumpThreading (or similar) in inline cost model
- [LLVMdev] Proposal : Function Notes
- [RFC][InlineCost] Modeling JumpThreading (or similar) in inline cost model
- [RFC][InlineCost] Modeling JumpThreading (or similar) in inline cost model