Skip to content
Prev 9977 / 10988 Next

[Rcpp-devel] coercion NULL to vector

On 17 April 2018 at 10:31, Dirk Eddelbuettel wrote:
|
| On 17 April 2018 at 15:09, Serguei Sokol wrote:
| | Hi,
| | 
| | I would like to re-discuss the subject of automatic coercion of
| | NULL to some vector in function parameter list. This old topic was
| | already raised e.g. here
| | https://stackoverflow.com/questions/34718570/rcpp-pass-vector-of-length-0-null-to-cppfunction
| | 
| | To resume, actually a function defined as (ivec is from RcppArmadillo package)
| | 
| | sourceCpp(code="
| |  ??? // [[Rcpp::depends(RcppArmadillo)]]
| |  ??? #include <RcppArmadillo.h>
| |  ??? using namespace arma;
| |  ??? // [[Rcpp::export]]
| |  ??? ivec f(ivec x) {return x+1;}
| | ")
| | 
| | and called as f(c()) will produce an error:
| | Error in f(c()) :
| |  ? Not compatible with requested type: [type=NULL; target=integer].
| | 
| | What I propose is (for this example) to mimic a call f(integer(0)) which gives:
| |  > f(integer(0))
| |  ???? [,1]
| | 
| | The following one-line patch would do the job:
| | diff --git a/inst/include/Rcpp/r_cast.h b/inst/include/Rcpp/r_cast.h
| | index e59fa799..c0ec0817 100644
| | --- a/inst/include/Rcpp/r_cast.h
| | +++ b/inst/include/Rcpp/r_cast.h
| | @@ -63,6 +63,7 @@ namespace Rcpp {
| |  ???????????? case LGLSXP:
| |  ???????????? case CPLXSXP:
| |  ???????????? case INTSXP:
| | +??????????? case NILSXP:
| |  ???????????????? return Rf_coerceVector(x, RTYPE);
| |  ???????????? default:
| |  ???????????????? const char* fmt = "Not compatible with requested type: "
| | 
| | 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 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):
[,1]
[,1]
Error in f() : argument "x" is missing, with no default
[1] "matrix"
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)
Error in g(NULL) : Not a matrix.
[,1]                                           
[1,]   NA
Error in g(vector()) : Not a matrix.
Error in g(integer()) : Not a matrix.
Is this really useful, and can you not use Nullable<> instead?

Dirk