Skip to content

[Rcpp-devel] Vector<>::create

5 messages · Dirk Eddelbuettel, Romain Francois

#
Hello,

I've commited Vector<>::create methods to support creation of any kind 
of vectors with named or unnamed objects. examples:

// creating an unamed integer vector
IntegerVector::create( 10, 20 ) ;

// creating a named character vector
CharacterVector::create( _["foo"] = "bar", _["bar"] = "foo" ) ;

// creating a named list
List::create( _["foo"] = 10, _["bar"] = true ) ;

The syntax :

_[.] = .

can be replaced by this for people who don't like _ :

Argument( . ) = .

so for example :

List::create( Argument("foo") = 10, Argument("bar") = true ) ;




I could not use Named as it is now because it wraps the object too early 
and so would only work for lists (which contains SEXP) and would not 
work for e.g. integer vectors.

Here the rhs of Argument::operator= is kept as a reference until it is 
effectively stored in the object, so Argument::operator= makes an object 
of the template class traits::named_object which create knows how to 
deal with, but the key is that named_object does not wrap but only 
contains reference.


The new question is : should "Argument" be called something else ? 
Should I rework all others clients of Named so that they use Argument 
instead (in that case I would then call it Named).

Romain
#
On 19 March 2010 at 14:01, Romain Francois wrote:
| I've commited Vector<>::create methods to support creation of any kind 
| of vectors with named or unnamed objects. examples:
| 
| // creating an unamed integer vector
| IntegerVector::create( 10, 20 ) ;
| 
| // creating a named character vector
| CharacterVector::create( _["foo"] = "bar", _["bar"] = "foo" ) ;
| 
| // creating a named list
| List::create( _["foo"] = 10, _["bar"] = true ) ;
| 
| The syntax :
| 
| _[.] = .
| 
| can be replaced by this for people who don't like _ :
| 
| Argument( . ) = .
| 
| so for example :
| 
| List::create( Argument("foo") = 10, Argument("bar") = true ) ;

Really nice work!
 
| I could not use Named as it is now because it wraps the object too early 
| and so would only work for lists (which contains SEXP) and would not 
| work for e.g. integer vectors.
| 
| Here the rhs of Argument::operator= is kept as a reference until it is 
| effectively stored in the object, so Argument::operator= makes an object 
| of the template class traits::named_object which create knows how to 
| deal with, but the key is that named_object does not wrap but only 
| contains reference.
| 
| The new question is : should "Argument" be called something else ? 
| Should I rework all others clients of Named so that they use Argument 
| instead (in that case I would then call it Named).

Tricky one. We'd be altering a published interfaces which is bad, but then
the paint is barely on these interfaces. I guess this can be argued either
way.  What do you think?   What do other lurkers thing?

Dirk
#
Le 19/03/10 15:03, Dirk Eddelbuettel a ?crit :
It was quite challenging ... but where is the fun otherwise ?
about this, instead of being a class, we make Named a templated 
function. With this I think we could preserve both syntax:

Named( "x" ) = 10 ;
Named( "x", 10 ) ;

I don't think anyone cares that Named is a class, as it is only 
typically used inside other constructs for its side effect.

I think this way we would just alter what Named is but keep what it is 
used for intact.

Romain
#
Done. Named is no longer a class but two templated functions. The 
interface is 100% preserved, and is extended to simpler vectors.

Not a single line of the unit tests has changed.

This shows that both interfaces can be used with simpler types:

fx <- cfunction( signature(), '
         return IntegerVector::create(
                 Named( "foo" ) = 20,
                 Named( "bar", 30 ) ) ;
', Rcpp = TRUE, includes = "using namespace Rcpp;" )


 > fx()
foo bar
  20  30

Romain

Le 19/03/10 15:35, Romain Francois a ?crit :

  
    
#
On 19 March 2010 at 17:05, Romain Francois wrote:
| Done. Named is no longer a class but two templated functions. The 
| interface is 100% preserved, and is extended to simpler vectors.
| 
| Not a single line of the unit tests has changed.
| 
| This shows that both interfaces can be used with simpler types:
| 
| fx <- cfunction( signature(), '
|          return IntegerVector::create(
|                  Named( "foo" ) = 20,
|                  Named( "bar", 30 ) ) ;
| ', Rcpp = TRUE, includes = "using namespace Rcpp;" )
| 
| 
|  > fx()
| foo bar
|   20  30

Chapeau!  Well done. 

Like other lethal weapons, C++ can be quite effective when handled by a professinal :-)

Dirk