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

Romain Francois romain at r-enthusiasts.com
Tue Mar 16 23:20:46 CET 2010


Oops. commited now.

Le 16/03/10 23:16, Douglas Bates a écrit :
>
> I don't see that commit.  I have SVN revision 909, which AFAICS is the
> latest version, and there is no mention of make_list or Rcpp::Argument
> that I can find.
>
> On Tue, Mar 16, 2010 at 5:49 AM, Romain Francois
> <romain.francois at dbmail.com>  wrote:
>> 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
>>
>>
>>
>
>


-- 
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