[Rcpp-devel] coercion NULL to vector
Dirk Eddelbuettel
edd at debian.org
Tue Apr 17 17:53:48 CEST 2018
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
More information about the Rcpp-devel
mailing list