[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):
sourceCpp("/tmp/serguei.cpp")
f(NULL)
[,1]
f(integer(0))
[,1]
f()
Error in f() : argument "x" is missing, with no default
class(f(NULL))
[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)
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? Dirk
http://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org