[Rcpp-devel] calling and R function from rcpp and evaluation

Romain Francois romain at r-enthusiasts.com
Thu Feb 6 12:47:59 CET 2014


Hi Antonio, 

This is about how R evaluation works. Might not just be what you think it is. 

When you use Rcpp and therefore .Call things are evaluated fairly early, at least earlier than what would happen with R, etc … you can reproduce what R does by using promises. For example this work in Rcpp11: 

// [[Rcpp::export]]
RawVector rcpp_serialize(Dots dots){
  Function serialize("serialize") ;
  return serialize( dots.promise(0), R_NilValue ) ;
}

Dots has not been implemented in Rcpp, but would not be too hard to port: 
https://github.com/romainfrancois/Rcpp11/blob/master/inst/include/Rcpp/Dots.h

But it would also need to fix Rcpp’s handling of recursive promises (i.e. promise of a promise of a promise). 



Alternatively, for a solution based on Rcpp, you can look in dplyr. The .data_dots function has most of the R-level logic
https://github.com/hadley/dplyr/blob/master/R/manip-df.r

And the C++ logic is mostly in DataDots.h
https://github.com/hadley/dplyr/blob/master/inst/include/tools/DataDots.h

Romain

Le 6 févr. 2014 à 02:07, Antonio Piccolboni <antonio at piccolboni.info> a écrit :

> Hi,
> I was wondering why I can serialize a call such as in
> 
> serialize(call("ripley"), NULL) 
> [1] 58 0a 00 00 00 02 00 03 00 02 00 02 03 00 00 00 00 06 00 00 00 01 00 04 00 09 00 00 00 06 72 69 70 6c 65 79 00 00 00 fe
> 
> but if I try from C++ the call gets evaluated
> 
>  library("Rcpp")
> 
>  rcpp.serialize = cppFunction(code="RObject my_serialize(RObject x){Function r_serialize(\"serialize\"); return r_serialize(x, R_NilValue);}")
> 
>  rcpp.serialize(10)
>  [1] 58 0a 00 00 00 02 00 03 00 02 00 02 03 00 00 00 00 0e 00 00 00 01 40 24 00 00 00 00 00 00
> # easy things work
> 
>  rcpp.serialize(call("ripley"))
> Error: could not find function "ripley"
> # wants to evaluate it
> 
>  unserialize(rcpp.serialize(call("sqrt", 2)))
> [1] 1.414214
> # How is one to serialize the call itself
> 
>  rcpp.serialize(list(call("ripley")))
>  [1] 58 0a 00 00 00 02 00 03 00 02 00 02 03 00 00 00 00 13 00 00 00 01 00 00 00 06 00 00 00 01 00 04 00 09 00 00 00 06 72 69 70 6c 65 79 00 00 00 fe
> #wrapping in a list is enough to stop evaluation
> 
>  eval(call("ripley"))
> Error in eval(expr, envir, enclos) : could not find function "ripley"
>  eval(list(call("ripley")))
> [[1]]
> ripley()
> 
> #OK that's consistent
> 
> 
> Could anyone enlighten me on the evaluation mechanism? Not saying it's broken, but certainly my expectations were off. Thanks
> 
> 
> Antonio
> _______________________________________________
> Rcpp-devel mailing list
> Rcpp-devel at lists.r-forge.r-project.org
> https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20140206/99859b2d/attachment.html>


More information about the Rcpp-devel mailing list