From edd at debian.org  Fri Mar 23 18:21:45 2012
From: edd at debian.org (Dirk Eddelbuettel)
Date: Fri, 23 Mar 2012 12:21:45 -0500
Subject: [Rd] .Call ref card
In-Reply-To: <EA95C1C3-6C6D-4DEB-81EC-A3D7BFF3EA21@r-project.org>
References: <mailman.29.1332414009.26932.r-devel@r-project.org>
	<4F6B2CE9.2090600@mayo.edu>
	<2933F897-6D3D-4DC0-AD38-2C73C8F01A4E@r-project.org>
	<87obror7jf.wl%rdiaz02@gmail.com>
	<928F07E9-B0AE-4E8A-839C-59A20CDA23C1@gmail.com>
	<4F6B652A.6050209@mayo.edu> <87fwczr4em.wl%rdiaz02@gmail.com>
	<EA95C1C3-6C6D-4DEB-81EC-A3D7BFF3EA21@r-project.org>
Message-ID: <20332.45353.257614.562136@max.nulle.part>


Awesome. I love the reference card. This will be useful.

But I couldn't resist recasting your final "silly" example into 

  a) inline use which I find generally easier than having to do R CMD SHLIB
     followed by dyn.load() 

  b) a comparison with Rcpp which looks just about the same minus some
     UPPERCASE terms stemming from the R API.  

     We turn error() into Rf_error() as that is a toggle Rcpp sets (given how
     error(), length(), etc conflict at times with things of the same name
     coming from somewhere else). Alternatively, we could also use 'throw
     std::range_error("invalid n")' which then calls Rf_error for us.

     It uses one templated cast to int, but the intent is as readable as
     asInteger. You could of course use asInteger too, as Doug eg prefers.

     It then declares on list type of the right size. Alloc and all that is
     done behind the scenes -- abstraction.  And the assignment of the
     unaltered SEXP type x that is prelicated may just be simpler. 

Code is below for both variants, and the same outputs.

Dirk

R> library(inline)
R> 
R> replicateToListC <- cfunction(signature(x="any", N="integer"), body='
+    int n = asInteger(N);
+    if (n < 0) error("N must be non-negative");
+    SEXP res = allocVector(VECSXP, n);
+    for (int i = 0; i < n; i++) SET_VECTOR_ELT(res, i, x);
+    return res;
+ ')
R> 
R> replicateToListC(1:2, -2)
Error in replicateToListC(1:2, -2) : N must be non-negative
R> replicateToListC(1:2, 2)
[[1]]
[1] 1 2

[[2]]
[1] 1 2

R> 
R> replicateToListCpp <- cxxfunction(signature(x="any", N="integer"), plugin="Rcpp", body='
+    int n = as<int>(N);
+    if (n < 0) Rf_error("N must be non-negative");
+    List res(n);
+    for (int i = 0; i < n; i++) res[i] = x;
+    return res;
+ ')
R> 
R> replicateToListCpp(1:2, -2)
Error in replicateToListCpp(1:2, -2) : N must be non-negative
R> replicateToListCpp(1:2, 2)
[[1]]
[1] 1 2

[[2]]
[1] 1 2

R> 
R> 


-- 
"Outside of a dog, a book is a man's best friend. Inside of a dog, it is too
dark to read." -- Groucho Marx



[Rd] .Call ref card
Dirk Eddelbuettel