MarcelK
2009-Aug-20 12:41 UTC
[Rd] Problem using findVar( ) in combination with R's lazy evaluation
Hi All, I have a few small questions about the usage of the C findVar( ) function when used in C code called with '.Call'. In my case I create an R function with an argument. This function calls some C code in which I use findVar( ) to retrieve the values from the argument. Ofcourse normally I would just give the values as argument to .Call, but in my project I need to use findVar for various reasons (can elaborate if needed, but it's not really relevant..) Below is a small example of an R function and the C code in which the problem shows: (skip to bold 'question' part if this is allready known) ----------# R function #-------- f <- function(x) { .Call("envtest", environment()) } ----------# C function #-------- SEXP envtest(SEXP rho) { SEXP data; PROTECT(data = allocVector(REALSXP, 1)); data = findVar(install("x"), rho); UNPROTECT(1); return(data); } ----------# END #----------- The result of this function is that it should print the contents of whatever is passed to the function f(x). But when executing the function, the result is:> f(10)<promise: 0x142db20> Ofcourse this is due to lazy-evaluation as I've also read in the thread http://www.nabble.com/confusion-about-evaluation.-to18561135.html#a18563086 here . To 'fix' it, I would need to do 'something' with 'x', so changing the function f() to: f <- function(x) { x = x .Call("envtest", environment()) } works as can be shown with:> f(10)[1] 10 ---------- My question on this subject is, how can I work around this 'x = x' or other similar statement (print(x) to prevent lazy-evaluation? To summarize, I would like to use findVar to retrieve values from R objects which are given as function arguments to the R-function and not to the C-function. Other than the above question, I'd also like to know if findVar( ) by default also checks parent environments (inherits argument?) when the object can not be found in the given environment (if not, should I look into passing the environment Hash etc?). And, as a last question, how can I retrieve the value from the R-constant 'pi' using findVar? If I try this I receive the error "REAL can only be applied to 'numeric' not a 'promise'". Thank you for any solutions or insights in these subjects, if more details are needed I'm happy to give them! Marcel Kempenaar ----------------> sessionInfo()R version 2.9.1 (2009-06-26) x86_64-pc-linux-gnu locale: LC_CTYPE=en_US.UTF-8;LC_NUMERIC=C;LC_TIME=nl_NL.UTF-8;LC_COLLATE=C;LC_MONETARY=C;LC_MESSAGES=en_US.UTF-8;LC_PAPER=nl_NL.UTF-8;LC_NAME=C;LC_ADDRESS=C;LC_TELEPHONE=C;LC_MEASUREMENT=en_US.UTF-8;LC_IDENTIFICATION=C attached base packages: [1] stats graphics grDevices utils datasets methods base -- View this message in context: http://www.nabble.com/Problem-using-findVar%28-%29-in-combination-with-R%27s-lazy-evaluation-tp25061253p25061253.html Sent from the R devel mailing list archive at Nabble.com.
Simon Urbanek
2009-Aug-20 13:06 UTC
[Rd] Problem using findVar( ) in combination with R's lazy evaluation
Marcel, On Aug 20, 2009, at 8:41 , MarcelK wrote:> I have a few small questions about the usage of the C findVar( ) > function when used in C code called with '.Call'. In my case I > create an R function with an argument. This function calls some C > code in which I use findVar( ) to retrieve the values from the > argument. Ofcourse normally I would just give the values as argument > to .Call, but in my project I need to use findVar for various > reasons (can elaborate if needed, but it's not really relevant..) > Below is a small example of an R function and the C code in which > the problem shows: (skip to bold 'question' part if this is > allready known) > > ----------# R function #-------- > > f <- function(x) { > .Call("envtest", environment()) > } > > ----------# C function #-------- > > SEXP envtest(SEXP rho) { > SEXP data; > PROTECT(data = allocVector(REALSXP, 1));Scrap that - you're allocating data and in the next line you're discarding it?!?> data = findVar(install("x"), rho);Just add if (TYPEOF(data) == PROMSXP) data = eval(data, rho); Cheers, Simon> UNPROTECT(1); > return(data); > } > > ----------# END #----------- > > The result of this function is that it should print the contents of > whatever > is passed to the function f(x). But when executing the function, the > result > is: > > >> f(10) > <promise: 0x142db20> > > Ofcourse this is due to lazy-evaluation as I've also read in the > thread > http://www.nabble.com/confusion-about-evaluation.-to18561135.html#a18563086 > here . > > To 'fix' it, I would need to do 'something' with 'x', so changing the > function f() to: > > f <- function(x) { > x = x > .Call("envtest", environment()) > } > > works as can be shown with: > >> f(10) > [1] 10 > > ---------- > > My question on this subject is, how can I work around this 'x = x' > or other > similar statement (print(x) to prevent lazy-evaluation? To > summarize, I > would like to use findVar to retrieve values from R objects which > are given > as function arguments to the R-function and not to the C-function. > > Other than the above question, I'd also like to know if findVar( ) by > default also checks parent environments (inherits argument?) when > the object > can not be found in the given environment (if not, should I look into > passing the environment Hash etc?). > > And, as a last question, how can I retrieve the value from the R- > constant > 'pi' using findVar? If I try this I receive the error "REAL can only > be > applied to 'numeric' not a 'promise'". > > Thank you for any solutions or insights in these subjects, if more > details > are needed I'm happy to give them! > > Marcel Kempenaar > > ---------------- > >> sessionInfo() > R version 2.9.1 (2009-06-26) > x86_64-pc-linux-gnu > > locale: > LC_CTYPE > = > en_US > .UTF > -8 > ;LC_NUMERIC > = > C > ;LC_TIME > = > nl_NL > .UTF > -8 > ;LC_COLLATE > = > C > ;LC_MONETARY > = > C > ;LC_MESSAGES > = > en_US > .UTF > -8 > ;LC_PAPER > = > nl_NL > .UTF > -8 > ;LC_NAME > = > C > ;LC_ADDRESS > =C;LC_TELEPHONE=C;LC_MEASUREMENT=en_US.UTF-8;LC_IDENTIFICATION=C > > attached base packages: > [1] stats graphics grDevices utils datasets methods base > > -- > View this message in context: http://www.nabble.com/Problem-using-findVar%28-%29-in-combination-with-R%27s-lazy-evaluation-tp25061253p25061253.html > Sent from the R devel mailing list archive at Nabble.com. > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > >
Duncan Murdoch
2009-Aug-20 14:14 UTC
[Rd] Problem using findVar( ) in combination with R's lazy evaluation
On 8/20/2009 8:41 AM, MarcelK wrote:> Hi All, > > I have a few small questions about the usage of the C findVar( ) function > when used in C code called with '.Call'. In my case I create an R function > with an argument. This function calls some C code in which I use findVar( ) > to retrieve the values from the argument. Ofcourse normally I would just > give the values as argument to .Call, but in my project I need to use > findVar for various reasons (can elaborate if needed, but it's not really > relevant..) Below is a small example of an R function and the C code in > which the problem shows: (skip to bold 'question' part if this is allready > known) > > ----------# R function #-------- > > f <- function(x) { > .Call("envtest", environment()) > } > > ----------# C function #-------- > > SEXP envtest(SEXP rho) { > SEXP data; > PROTECT(data = allocVector(REALSXP, 1)); > data = findVar(install("x"), rho); > UNPROTECT(1); > return(data); > } > > ----------# END #----------- > > The result of this function is that it should print the contents of whatever > is passed to the function f(x). But when executing the function, the result > is: > > >> f(10) > <promise: 0x142db20> > > Ofcourse this is due to lazy-evaluation as I've also read in the thread > http://www.nabble.com/confusion-about-evaluation.-to18561135.html#a18563086 > here . > > To 'fix' it, I would need to do 'something' with 'x', so changing the > function f() to: > > f <- function(x) { > x = x > .Call("envtest", environment()) > }The standard thing to do is to call force(), i.e. instead of x = x, call force(x). But Simon's solution is better, especially if you don't know in advance which arg you're going to be getting. Duncan Murdoch> > works as can be shown with: > >> f(10) > [1] 10 > > ---------- > > My question on this subject is, how can I work around this 'x = x' or other > similar statement (print(x) to prevent lazy-evaluation? To summarize, I > would like to use findVar to retrieve values from R objects which are given > as function arguments to the R-function and not to the C-function. > > Other than the above question, I'd also like to know if findVar( ) by > default also checks parent environments (inherits argument?) when the object > can not be found in the given environment (if not, should I look into > passing the environment Hash etc?). > > And, as a last question, how can I retrieve the value from the R-constant > 'pi' using findVar? If I try this I receive the error "REAL can only be > applied to 'numeric' not a 'promise'". > > Thank you for any solutions or insights in these subjects, if more details > are needed I'm happy to give them! > > Marcel Kempenaar > > ---------------- > >> sessionInfo() > R version 2.9.1 (2009-06-26) > x86_64-pc-linux-gnu > > locale: > LC_CTYPE=en_US.UTF-8;LC_NUMERIC=C;LC_TIME=nl_NL.UTF-8;LC_COLLATE=C;LC_MONETARY=C;LC_MESSAGES=en_US.UTF-8;LC_PAPER=nl_NL.UTF-8;LC_NAME=C;LC_ADDRESS=C;LC_TELEPHONE=C;LC_MEASUREMENT=en_US.UTF-8;LC_IDENTIFICATION=C > > attached base packages: > [1] stats graphics grDevices utils datasets methods base >