[Rcpp-devel] Good idioms for creating a named list?

Romain Francois romain.francois at dbmail.com
Tue Mar 16 11:49:30 CET 2010


Hello,

I have now commited make_list as a set of templates taking variable 
number of arguments and creating named generic vectors. There is again 
some code bloat involved and it handles up to 20 arguments. (this is not 
painful to make it 50 or 100, but I think 20 is good enough for now).

For example (see more of this in the runit.make.list.R file):

fx <- cfunction(signature(),'
		return make_list(
			Named("a") = 1 ,
			Named("b") = 2 ,
			Named("c") = "foobar",
			Named("d") = 4.0 ) ;	
	',
	Rcpp = TRUE, includes = "using namespace Rcpp; " )
	
I've also added the Argument class, which is somewhat similar to Named, 
except that it does not hold the object (only its name) and it is the 
templated operator= that makes a Named object from it. This means that 
the code above can be replaced by this:

		return make_list(
			Argument("a") = 1 ,
			Argument("b") = 2 ,
			Argument("c") = "foobar",
			Argument("d") = 4.0 ) ;	


But it can also be used to first declare a set of arguments that a given 
package uses a lot, and then just use them with a nice construct. For 
example :

// declare the arguments:
// maybe in some header file
Argument x("x"), y("y") ;

// use them:
make_list( x = 2, y = "foo" ) ;
Language call( "somefunction", x = 2, y = "foo" ) ;
Pairlist pl( x = 2, y = 3 )
Function f("somefunction" ) ;
f( x = 2, y = 3 )


For example minqa uses the same arguments several times : "par", "fval", 
"feval", "intpval", so maybe this would be useful to have this on top of 
the file:

static Rcpp::Argument par("par") ;
static Rcpp::Argument fval("fval") ;
static Rcpp::Argument feval("feval") ;
static Rcpp::Argument minpval("minpval") ;

and then replace :

Rcpp::List rr(Rcpp::Pairlist(Rcpp::Named("par", par),
				 Rcpp::Named("fval",
					     F77_NAME(calfun)(&n,
							      par.begin(),
							      ip.begin())),
				 Rcpp::Named("feval", rho.get(".feval.")),
				 Rcpp::Named("intpval", fval)));


by :

Rcpp::List rr = make_list(
	par  = par_,
	fval = F77_NAME(calfun)(&n, par.begin(), ip.begin()),
	feval = rho.get(".feval."),
	intpval = fval_
	)

(notice the underscore in par_ and fval_ because I use the variable name 
for the Argument instance ... but this is just an example.

Romain


Le 15/03/10 21:26, Romain Francois a écrit :
>
> Le 15/03/10 21:13, Douglas Bates a écrit :
>>
>> R functions often return a named list, sometimes with an S3 class
>> attached.  Over the weekend I exchanged some email with Dirk and
>> Romain about good ways to create such a return object.  The way that I
>> am currently doing so is through creating an Rcpp::Pairlist of
>> Rcpp::Named objects then converting the Pairlist to a List.
>>
>> Another possibility would be to create a
>>
>> std::map<std::string, Rcpp::Robject>
>>
>> add components to the map and wrap the result.  I can check for
>> myself, of course, but can someone tell me off the bat what the form
>> of the R object resulting from Rcpp::wrap applied to such an object
>> would be?
>
> If all works as expected, you should get exactly what you want : a named
> generic vector.
>
> What we need is new constructors in Rcpp::List, but this is not as easy
> as it sounds (Rcpp::List is actually cooked from a template, etc ...).
> Maybe we can do some templated factory functions. Something like:
>
> template<typename T1, typename T2>
> Rcpp::make_list( const T1&  t1, const T2&  t2)
>
> ...
>
> with the appropriate handling of the Named class, so that we could do
> things like :
>
>
> List res = make_list(
> 	Named( "x" ) = 1,
> 	Named( "y  ) = "foo"
>    ) ;
>
> or (this does not pass the Dirk test though):
>
> List res = make_list(
> 	_["x"] = 1,
> 	_["y"] = "foo" ) ;
>
> Romain
>


-- 
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
http://romainfrancois.blog.free.fr
|- http://tr.im/OIXN : raster images and RImageJ
|- http://tr.im/OcQe : Rcpp 0.7.7
`- http://tr.im/O1wO : highlight 0.1-5




More information about the Rcpp-devel mailing list