[Rcpp-devel] more sugar

Romain Francois romain at r-enthusiasts.com
Thu Jun 17 22:54:14 CEST 2010


Hi,

Following up on http://news.gmane.org/gmane.comp.lang.r.rcpp
I've commited quite a bit of code today.

The idea of sugar really is to bring a subset of the R syntax right into 
C++.

First I had to change a few implementation details of the Vector class 
so that one of its base class implements CRTP: 
http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern

Then, I made the previously advertised functions any, all, etc ... more 
generic through the base template class VectorBase.

Then, I added some more syntax. Currently sugar has the functions:

any, all, is_na, seq_along, seq_len

and knows about the operators <,>,<=,>=,!=,==,+



Here are a few selected examples (from the unit test suite):

test.sugar.plus <- function( ){

	fx <- cxxfunction( signature( x = "integer" ), '
		IntegerVector xx(x) ;
		return List::create(
			xx + 10,
			10 + xx,
			xx + xx
			) ;
	', plugin = "Rcpp" )
	
	checkEquals( fx(1:10) , list( 11:20,11:20,1:10+1:10)  )
}

We start of with

IntegerVector xx(x) ;

which should be familiar to people using the Rcpp API... nothing new here.

Then the expressions "xx + 10", "10 + xx", and "xx + xx" are new things. 
They do what you would do in R like this:

 > x <- 1:10
 > x + 10
  [1] 11 12 13 14 15 16 17 18 19 20
 > 10 + x
  [1] 11 12 13 14 15 16 17 18 19 20
 > x + x
  [1]  2  4  6  8 10 12 14 16 18 20

The big difference is that, unlike R, Rcpp sugar expressions are managed 
at compile time, thanks to the technique of expression templates (see 
also Armadillo or Blitz++).


Another example:

	fx <- cxxfunction( signature( x = "numeric" ), '
		NumericVector xx(x) ;
		return all( xx <= 5.0 ) ;
	
	', plugin = "Rcpp" )
	
	fx( c(1:1000000) )

Here, R would first allocate a logical vector to store the result of "xx 
<= 5.0" (a logical vector of size 1000000) and then apply "all".

The "all" function in Rcpp is lazy, so it does not allocate the vector, 
and only has to do 6 comparisons (1,2,3,4,5,6) to decide that the result 
is FALSE.


sugar expressions can be combined, so for example this works:

test.sugar.plus.all <- function( ){

	fx <- cxxfunction( signature( x = "integer" ), '
		IntegerVector xx(x) ;
		return all( (xx+xx) < 10 ) ;
	', plugin = "Rcpp" )
	
	checkEquals( fx(1:10) , FALSE )
}


There is still much work to be done (see the TODO file), but I think 
this has quite some potential.

Romain

-- 
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
http://romainfrancois.blog.free.fr
|- http://bit.ly/98Uf7u : Rcpp 0.8.1
|- http://bit.ly/c6YnCi : graph gallery collage
`- http://bit.ly/bZ7ltC : inline 0.3.5



More information about the Rcpp-devel mailing list