[Rcpp-devel] coercion NULL to vector

Serguei Sokol serguei.sokol at gmail.com
Wed Apr 18 11:56:41 CEST 2018


Le 17/04/2018 à 17:53, Dirk Eddelbuettel a écrit :
> 
> On 17 April 2018 at 10:31, Dirk Eddelbuettel wrote:
> |
> | On 17 April 2018 at 15:09, Serguei Sokol wrote:
...
> | | It will automatically coerce NULL to a declared vector type.
> | | It's a more primitive solution than Nullable<T> but in many cases
> | | it can be largely sufficient and make code look shorter and clearer.
> | |
> | | Will it break something in established usage habits? Is it compatible with your plans for Rcpp?
> | | I can prepare a PR if you decide to include it.
> |
> | We could test that.  It may not do harm -- so I just turned on a rev.dep
> | check for it.
> |
> | Can you open an issue for it on GH though?  Better visibility and easier 'per
> | concrete topic' discussion.
I was just about to do so when I saw your post here. So let decide if
the semantic is useful or not and if yes, we'll switch to GH. OK?

> 
> I am not convinced that the semantics are useful.  Your example works on the
> arma type (where we our very old design issue of always returning a matrix):
What is returned: a matrix or a vector is not important here. By the way, it is
already resolved by an optional RCPP_ARMADILLO_RETURN_COLVEC_AS_VECTOR macro, remember?
The point here is how the /input/ NULL is interpreted. Is it coerced to smth or
just an error is thrown?

> 
>> sourceCpp("/tmp/serguei.cpp")
>> f(NULL)
>       [,1]
>> f(integer(0))
>       [,1]
>> f()
> Error in f() : argument "x" is missing, with no default
Normal. If you want to make the parameter optional, you have to declare
vec f(Rcpp::NumericVector x=R_NilValue) {return x+1;}
 > f()
      [,1]
It does not work yet with 'vec' type but it could with an appropriate patch.
We are just discussing the usefulness of semantics not yet the patch.

>> class(f(NULL))
> [1] "matrix"
(not a big deal what is returned as discussed above).

>>
> 
> But if I do the same with Rcpp types, say a matrix via
> 
> // [[Rcpp::export]]
> Rcpp::NumericMatrix g(Rcpp::NumericMatrix x) { return x+1; }
> 
> then I get more restrictive behaviour (as NumericMatrix tests for matrix)
Right. I think that the next logical step would be to allow an automatic
coercion of atomic vectors to matrices too. As in R
 > as.matrix(integer(0))
      [,1]
we got a matrix of dims (0, 1) we could make the same available in Rcpp.
More generally, a vector x could be coerced into a matrix of dims (length(x), 1)
(once again just as in R as.matrix())

> 
>> sourceCpp("/tmp/serguei.cpp")
>> g(NULL)
> Error in g(NULL) : Not a matrix.
>> g(matrix())
>       [,1]
> [1,]   NA
>> g(vector())
> Error in g(vector()) : Not a matrix.
>> g(integer())
> Error in g(integer()) : Not a matrix.
>>   
> 
> 
> Is this really useful, and can you not use Nullable<> instead?
Sure I can, but as I already said, my thought is to make the code
looking simpler and clearer in this kind of situations where automatic
coercion does sufficient job. Nullable<T> is much more flexible than that
but more expensive in coding on user's side.

Serguei.


More information about the Rcpp-devel mailing list