[Rd] how to call a function from C
Hi, In Rcpp, we now have a Function class to encapsulate functions (they cover all three kinds, but this may change). To call the function, what we do is generate a call with the function as the first node and then evaluate the call. SEXP stats = PROTECT( R_FindNamespace( mkString( stats) ) ); SEXP rnorm = PROTECT( findVarInFrame( stats, install( rnorm) ) ) ; SEXP call = PROTECT( LCONS( rnorm, CONS( ScalarInteger(10), CONS(ScalarReal(0), R_NilValue ) ) ) ); SEXP res = PROTECT( eval( call , R_GlobalEnv ) ); UNPROTECT(4) ; return res ; It works, but I was wondering if there was another way. I've seen applyClosure, but I'm not sure I should attempt to use it or if using a call like above is good enough. Romain PS: using Rcpp's C++ classes you would express the code above as : Environment stats(package:stats) ; Function rnorm = stats.get( rnorm ) return rnorm( 10, 0.0 ) ; -- Romain Francois Professional R Enthusiast +33(0) 6 28 91 30 30 http://romainfrancois.blog.free.fr |- http://tr.im/KfKn : Rcpp 0.7.2 |- http://tr.im/JOlc : External pointers with Rcpp `- http://tr.im/JFqa : R Journal, Volume 1/2, December 2009 __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] how to call a function from C
Hi, In Rcpp, we now have a Function class to encapsulate functions (they cover all three kinds, but this may change). Just a note on that: there is probably no hurry to do so. rpy2 is also having CLOSXP, BUILTINSXP, and SPECIALSXP represented as one function-like class and seems to be behave reasonably while a lot of other things seem more urgent to sort out. To call the function, what we do is generate a call with the function as the first node and then evaluate the call. SEXP stats = PROTECT( R_FindNamespace( mkString( stats) ) ); SEXP rnorm = PROTECT( findVarInFrame( stats, install( rnorm) ) ) ; SEXP call = PROTECT( LCONS( rnorm, CONS( ScalarInteger(10), CONS(ScalarReal(0), R_NilValue ) ) ) ); SEXP res = PROTECT( eval( call , R_GlobalEnv ) ); UNPROTECT(4) ; return res ; It works, but I was wondering if there was another way. I've seen applyClosure, but I'm not sure I should attempt to use it or if using a call like above is good enough. Using R_tryEval() will let you evaluate an expression in a given environment, as well as capture an eventual error occurring during its evaluation (and translate it as an exception). Romain PS: using Rcpp's C++ classes you would express the code above as : Environment stats(package:stats) ; Function rnorm = stats.get( rnorm ) return rnorm( 10, 0.0 ) ; Feel free to snoop in rpy2's rpy/rinterface/rinterface.c and look for do_try_eval. The behavior looks very similar, the above snippet in rpy2 would write like: from rpy2.robjects.packages import importr stats = importr('stats') stats.rnorm(10, 0.0) -- Romain Francois Professional R Enthusiast +33(0) 6 28 91 30 30 http://romainfrancois.blog.free.fr |- http://tr.im/KfKn : Rcpp 0.7.2 |- http://tr.im/JOlc : External pointers with Rcpp `- http://tr.im/JFqa : R Journal, Volume 1/2, December 2009 __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] how to call a function from C
On 01/14/2010 12:42 PM, Laurent Gautier wrote: Hi, In Rcpp, we now have a Function class to encapsulate functions (they cover all three kinds, but this may change). Just a note on that: there is probably no hurry to do so. rpy2 is also having CLOSXP, BUILTINSXP, and SPECIALSXP represented as one function-like class and seems to be behave reasonably while a lot of other things seem more urgent to sort out. To call the function, what we do is generate a call with the function as the first node and then evaluate the call. SEXP stats = PROTECT( R_FindNamespace( mkString( stats) ) ); SEXP rnorm = PROTECT( findVarInFrame( stats, install( rnorm) ) ) ; SEXP call = PROTECT( LCONS( rnorm, CONS( ScalarInteger(10), CONS(ScalarReal(0), R_NilValue ) ) ) ); SEXP res = PROTECT( eval( call , R_GlobalEnv ) ); UNPROTECT(4) ; return res ; It works, but I was wondering if there was another way. I've seen applyClosure, but I'm not sure I should attempt to use it or if using a call like above is good enough. Using R_tryEval() will let you evaluate an expression in a given environment, as well as capture an eventual error occurring during its evaluation (and translate it as an exception). Sure. I did not want to over-complicate the question. I'm currently reviewing tryEval and its underlying R_TopLevelExec which does not give me enough : when the error occurs, it'd be useful that the function returns the condition object instead of NULL. Romain PS: using Rcpp's C++ classes you would express the code above as : Environment stats(package:stats) ; Function rnorm = stats.get( rnorm ) return rnorm( 10, 0.0 ) ; Feel free to snoop in rpy2's rpy/rinterface/rinterface.c and look for do_try_eval. The behavior looks very similar, the above snippet in rpy2 would write like: from rpy2.robjects.packages import importr stats = importr('stats') stats.rnorm(10, 0.0) nice -- Romain Francois Professional R Enthusiast +33(0) 6 28 91 30 30 http://romainfrancois.blog.free.fr |- http://tr.im/KfKn : Rcpp 0.7.2 |- http://tr.im/JOlc : External pointers with Rcpp `- http://tr.im/JFqa : R Journal, Volume 1/2, December 2009 __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] how to call a function from C
On 1/14/10 1:16 PM, Romain Francois wrote: On 01/14/2010 12:42 PM, Laurent Gautier wrote: Hi, In Rcpp, we now have a Function class to encapsulate functions (they cover all three kinds, but this may change). Just a note on that: there is probably no hurry to do so. rpy2 is also having CLOSXP, BUILTINSXP, and SPECIALSXP represented as one function-like class and seems to be behave reasonably while a lot of other things seem more urgent to sort out. To call the function, what we do is generate a call with the function as the first node and then evaluate the call. SEXP stats = PROTECT( R_FindNamespace( mkString( stats) ) ); SEXP rnorm = PROTECT( findVarInFrame( stats, install( rnorm) ) ) ; SEXP call = PROTECT( LCONS( rnorm, CONS( ScalarInteger(10), CONS(ScalarReal(0), R_NilValue ) ) ) ); SEXP res = PROTECT( eval( call , R_GlobalEnv ) ); UNPROTECT(4) ; return res ; It works, but I was wondering if there was another way. I've seen applyClosure, but I'm not sure I should attempt to use it or if using a call like above is good enough. Using R_tryEval() will let you evaluate an expression in a given environment, as well as capture an eventual error occurring during its evaluation (and translate it as an exception). Sure. I did not want to over-complicate the question. I'm currently reviewing tryEval and its underlying R_TopLevelExec which does not give me enough : when the error occurs, it'd be useful that the function returns the condition object instead of NULL. I possibly went the same path, and ended with R_tryEval. When looking at it, I could not figure out any way to get what I wanted outside using geterrmessage in base. The error string is in the variable errbuf (in src/main/error.c), with no obvious route to access it (and if truly no route, this might be something missing from the R C-API). Romain PS: using Rcpp's C++ classes you would express the code above as : Environment stats(package:stats) ; Function rnorm = stats.get( rnorm ) return rnorm( 10, 0.0 ) ; Feel free to snoop in rpy2's rpy/rinterface/rinterface.c and look for do_try_eval. The behavior looks very similar, the above snippet in rpy2 would write like:p/ I meant do_eval_expr. from rpy2.robjects.packages import importr stats = importr('stats') stats.rnorm(10, 0.0) nice __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] how to call a function from C
The Rcpp library in RcppTemplate (the package that Rcpp forked from) simplifies the process of calling functions from C++. The design goal was to enable users to focus on scientific problem solving rather than interface problems and low-level R internals (by hiding these details and documenting everything). The current Rcpp package is a mashup of the packages RcppTemplate (old version), inline, and RInside that involves a fair amount of low-level R hacking, and this is probably consistent with the preferences of most readers of this list. If I am mistaken and there are any users of RcppTemplate please let me know, as I am thinking about reoganizing that package to minimize confusion with the fork. Thanks, Dominick On Thu, Jan 14, 2010 at 7:16 AM, Romain Francois romain.franc...@dbmail.com wrote: On 01/14/2010 12:42 PM, Laurent Gautier wrote: Hi, In Rcpp, we now have a Function class to encapsulate functions (they cover all three kinds, but this may change). Just a note on that: there is probably no hurry to do so. rpy2 is also having CLOSXP, BUILTINSXP, and SPECIALSXP represented as one function-like class and seems to be behave reasonably while a lot of other things seem more urgent to sort out. To call the function, what we do is generate a call with the function as the first node and then evaluate the call. SEXP stats = PROTECT( R_FindNamespace( mkString( stats) ) ); SEXP rnorm = PROTECT( findVarInFrame( stats, install( rnorm) ) ) ; SEXP call = PROTECT( LCONS( rnorm, CONS( ScalarInteger(10), CONS(ScalarReal(0), R_NilValue ) ) ) ); SEXP res = PROTECT( eval( call , R_GlobalEnv ) ); UNPROTECT(4) ; return res ; It works, but I was wondering if there was another way. I've seen applyClosure, but I'm not sure I should attempt to use it or if using a call like above is good enough. Using R_tryEval() will let you evaluate an expression in a given environment, as well as capture an eventual error occurring during its evaluation (and translate it as an exception). Sure. I did not want to over-complicate the question. I'm currently reviewing tryEval and its underlying R_TopLevelExec which does not give me enough : when the error occurs, it'd be useful that the function returns the condition object instead of NULL. Romain PS: using Rcpp's C++ classes you would express the code above as : Environment stats(package:stats) ; Function rnorm = stats.get( rnorm ) return rnorm( 10, 0.0 ) ; Feel free to snoop in rpy2's rpy/rinterface/rinterface.c and look for do_try_eval. The behavior looks very similar, the above snippet in rpy2 would write like: from rpy2.robjects.packages import importr stats = importr('stats') stats.rnorm(10, 0.0) nice -- Romain Francois Professional R Enthusiast +33(0) 6 28 91 30 30 http://romainfrancois.blog.free.fr |- http://tr.im/KfKn : Rcpp 0.7.2 |- http://tr.im/JOlc : External pointers with Rcpp `- http://tr.im/JFqa : R Journal, Volume 1/2, December 2009 __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel [[alternative HTML version deleted]] __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] how to call a function from C
On 01/14/2010 03:50 PM, Dominick Samperi wrote: The Rcpp library in RcppTemplate (the package that Rcpp forked from) simplifies the process of calling functions from C++. The design goal was to enable users to focus on scientific problem solving rather than interface problems and low-level R internals (by hiding these details and documenting everything). Hello Dominick, In the Rcpp package, you'd call the rnorm function like this : /* grab the environment called package:stats */ Environment stats(package:stats) ; /* or like this if you want the namespace */ /* Environment stats = Environment::namespace_env(stats) ;*/ /* grab function called 'rnorm' from this environment */ Function rnorm = stats.get(rnorm ) ; /* call the function, about the same way you'd do in R * * rnorm( 10L, sd = 100 ) */ return rnorm( 10, Named( sd, 100.0 ) ) ; All involved SEXP are encapsulated in suitable C++ objects, such as Environment, Function, etc ... the user does not need to know about SEXP, does not need to care about the PROTECT/UNPROTECT dance, etc ... Please let me know which of these three lines of C++ code you consider to be low level R internals. It might be interesting that you post how you would invoke the same using RcppTemplate. The current Rcpp package is a mashup of the packages RcppTemplate (old version), inline, and RInside It is not anything even kind of close to that. There was code from the inline package at some point, but it is now back into inline, which has been improved to support easy inlining of code making use of Rcpp. There is nothing of RInside in Rcpp, it goes the other way, RInside depends on Rcpp and uses its features to ease embedding R into an existing C++ application The Rcpp package is under a lot of changes. See : - http://dirk.eddelbuettel.com/blog/2010/01/12/#rcpp_0.7.2 - http://dirk.eddelbuettel.com/blog/2010/01/02/#rcpp_0.7.1 - http://romainfrancois.blog.free.fr/index.php?post/2010/01/13/Rcpp-0.7.2-is-out - http://romainfrancois.blog.free.fr/index.php?post/2010/01/08/External-pointers-with-Rcpp - http://romainfrancois.blog.free.fr/index.php?post/2009/12/29/new-things-in-Rcpp that involves a fair amount of low-level R hacking, and this is probably consistent with the preferences of most readers of this list. Can you be more specific ? The whole purpose of the package is to hide the R API. The user does not need to know the R API to use the classes of Rcpp. We however indeed use and abuse the R API a lot internally. Romain If I am mistaken and there are any users of RcppTemplate please let me know, as I am thinking about reoganizing that package to minimize confusion with the fork. Thanks, Dominick On Thu, Jan 14, 2010 at 7:16 AM, Romain Francois romain.franc...@dbmail.com mailto:romain.franc...@dbmail.com wrote: On 01/14/2010 12:42 PM, Laurent Gautier wrote: Hi, In Rcpp, we now have a Function class to encapsulate functions (they cover all three kinds, but this may change). Just a note on that: there is probably no hurry to do so. rpy2 is also having CLOSXP, BUILTINSXP, and SPECIALSXP represented as one function-like class and seems to be behave reasonably while a lot of other things seem more urgent to sort out. To call the function, what we do is generate a call with the function as the first node and then evaluate the call. SEXP stats = PROTECT( R_FindNamespace( mkString( stats) ) ); SEXP rnorm = PROTECT( findVarInFrame( stats, install( rnorm) ) ) ; SEXP call = PROTECT( LCONS( rnorm, CONS( ScalarInteger(10), CONS(ScalarReal(0), R_NilValue ) ) ) ); SEXP res = PROTECT( eval( call , R_GlobalEnv ) ); UNPROTECT(4) ; return res ; It works, but I was wondering if there was another way. I've seen applyClosure, but I'm not sure I should attempt to use it or if using a call like above is good enough. Using R_tryEval() will let you evaluate an expression in a given environment, as well as capture an eventual error occurring during its evaluation (and translate it as an exception). Sure. I did not want to over-complicate the question. I'm currently reviewing tryEval and its underlying R_TopLevelExec which does not give me enough : when the error occurs, it'd be useful that the function returns the condition object instead of NULL. Romain PS: using Rcpp's C++ classes you would express the code above as : Environment stats(package:stats) ; Function rnorm = stats.get( rnorm ) return rnorm( 10, 0.0 ) ; Feel free to snoop in rpy2's rpy/rinterface/rinterface.c and look for do_try_eval. The behavior looks very similar, the above
Re: [Rd] how to call a function from C
On Thu, Jan 14, 2010 at 10:20 AM, Romain Francois romain.franc...@dbmail.com wrote: It might be interesting that you post how you would invoke the same using RcppTemplate. Sorry, I will not complete with my own work. The point of my last post was to see if anybody still uses RcppTemplate so I can decide what to do with that package. [[alternative HTML version deleted]] __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] how to call a function from C
On 01/14/2010 02:27 PM, Laurent Gautier wrote: On 1/14/10 1:16 PM, Romain Francois wrote: On 01/14/2010 12:42 PM, Laurent Gautier wrote: Hi, In Rcpp, we now have a Function class to encapsulate functions (they cover all three kinds, but this may change). Just a note on that: there is probably no hurry to do so. rpy2 is also having CLOSXP, BUILTINSXP, and SPECIALSXP represented as one function-like class and seems to be behave reasonably while a lot of other things seem more urgent to sort out. To call the function, what we do is generate a call with the function as the first node and then evaluate the call. SEXP stats = PROTECT( R_FindNamespace( mkString( stats) ) ); SEXP rnorm = PROTECT( findVarInFrame( stats, install( rnorm) ) ) ; SEXP call = PROTECT( LCONS( rnorm, CONS( ScalarInteger(10), CONS(ScalarReal(0), R_NilValue ) ) ) ); SEXP res = PROTECT( eval( call , R_GlobalEnv ) ); UNPROTECT(4) ; return res ; It works, but I was wondering if there was another way. I've seen applyClosure, but I'm not sure I should attempt to use it or if using a call like above is good enough. Using R_tryEval() will let you evaluate an expression in a given environment, as well as capture an eventual error occurring during its evaluation (and translate it as an exception). Sure. I did not want to over-complicate the question. I'm currently reviewing tryEval and its underlying R_TopLevelExec which does not give me enough : when the error occurs, it'd be useful that the function returns the condition object instead of NULL. I possibly went the same path, and ended with R_tryEval. When looking at it, I could not figure out any way to get what I wanted outside using geterrmessage in base. The error string is in the variable errbuf (in src/main/error.c), with no obvious route to access it (and if truly no route, this might be something missing from the R C-API). It seems to be the regular way around this gap. Martin Morgan gave the same advice (using geterrmessage) here last week. it only gives you the error message though I've been staring at R_ToplevelExec, begincontext and addCondHands. Some day, I'll understand how to connect the dots. Not today though. Romain Romain PS: using Rcpp's C++ classes you would express the code above as : Environment stats(package:stats) ; Function rnorm = stats.get( rnorm ) return rnorm( 10, 0.0 ) ; Feel free to snoop in rpy2's rpy/rinterface/rinterface.c and look for do_try_eval. The behavior looks very similar, the above snippet in rpy2 would write like:p/ I meant do_eval_expr. thanks. from rpy2.robjects.packages import importr stats = importr('stats') stats.rnorm(10, 0.0) nice -- Romain Francois Professional R Enthusiast +33(0) 6 28 91 30 30 http://romainfrancois.blog.free.fr |- http://tr.im/KfKn : Rcpp 0.7.2 |- http://tr.im/JOlc : External pointers with Rcpp `- http://tr.im/JFqa : R Journal, Volume 1/2, December 2009 __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] how to call a function from C
On Thu, 14 Jan 2010, Romain Francois wrote: On 01/14/2010 12:42 PM, Laurent Gautier wrote: Hi, In Rcpp, we now have a Function class to encapsulate functions (they cover all three kinds, but this may change). Just a note on that: there is probably no hurry to do so. rpy2 is also having CLOSXP, BUILTINSXP, and SPECIALSXP represented as one function-like class and seems to be behave reasonably while a lot of other things seem more urgent to sort out. To call the function, what we do is generate a call with the function as the first node and then evaluate the call. SEXP stats = PROTECT( R_FindNamespace( mkString( stats) ) ); SEXP rnorm = PROTECT( findVarInFrame( stats, install( rnorm) ) ) ; SEXP call = PROTECT( LCONS( rnorm, CONS( ScalarInteger(10), CONS(ScalarReal(0), R_NilValue ) ) ) ); SEXP res = PROTECT( eval( call , R_GlobalEnv ) ); UNPROTECT(4) ; return res ; It works, but I was wondering if there was another way. I've seen applyClosure, but I'm not sure I should attempt to use it or if using a call like above is good enough. Using R_tryEval() will let you evaluate an expression in a given environment, as well as capture an eventual error occurring during its evaluation (and translate it as an exception). Sure. I did not want to over-complicate the question. I'm currently reviewing tryEval and its underlying R_TopLevelExec which does not give me enough : when the error occurs, it'd be useful that the function returns the condition object instead of NULL. R_TopLevelExec, and hence R_tryEval, don't quite do what some users expect and maybe would like. There are two issues. The TopLevel part means that conceptually this call runs in its own stack, which means things like calling error handlers set up outside this call are not visible, and Sys.whatever functions don't see the rest of the stack (or at least should not). A call to one of these is conceptually a bit like asking a separate thread to evaluate the expression and waiting for the result. (I believe his mechanism was added to handle finalizer code in the GC, where this makes sense, but I may have my history wrong.) The other issue is that what R_tryEval catches is not errors, it is longjmp attempts. The vast majority of these will come from attempts to pass errors to exiting handlers, but there are other possibilities, such as invoking an abort restart (which jumps to top level). It might be useful to provide a C level interface for catching errors as well as other jumps and for allowing C code to do cleanup operations and then continue those jumps if appropriate, but getting that right is fairly tricky and certainly hasn't risen high enough on my priority list to warrant the investment of time. The interface would have to abstract over implementation details though: we definitely do not want to expose and commit to current details of the context stack implementation. luke Romain PS: using Rcpp's C++ classes you would express the code above as : Environment stats(package:stats) ; Function rnorm = stats.get( rnorm ) return rnorm( 10, 0.0 ) ; Feel free to snoop in rpy2's rpy/rinterface/rinterface.c and look for do_try_eval. The behavior looks very similar, the above snippet in rpy2 would write like: from rpy2.robjects.packages import importr stats = importr('stats') stats.rnorm(10, 0.0) nice -- Luke Tierney Chair, Statistics and Actuarial Science Ralph E. Wareham Professor of Mathematical Sciences University of Iowa Phone: 319-335-3386 Department of Statistics andFax: 319-335-3017 Actuarial Science 241 Schaeffer Hall email: l...@stat.uiowa.edu Iowa City, IA 52242 WWW: http://www.stat.uiowa.edu __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel