[Rcpp-devel] Idiom for accessing scalars

Romain François romain at r-enthusiasts.com
Sat Jan 7 18:30:01 CET 2012


Le 07/01/12 17:04, Douglas Bates a écrit :
> 2012/1/7 Romain François<romain at r-enthusiasts.com>:
>> Le 06/01/12 20:46, Douglas Bates a écrit :
>>
>>> On Fri, Jan 6, 2012 at 1:12 PM, Dirk Eddelbuettel<edd at debian.org>    wrote:
>>>> On 6 January 2012 at 12:59, Douglas Bates wrote:
>>>> | On Fri, Jan 6, 2012 at 12:39 PM, John Chambers<jmc at stat.stanford.edu>
>>>>   wrote:
>>>> |>    The "Rf_" part of the API in particular is ugly and somewhat of an
>>>> add-on
>>>> |>    forced in a few examples by the use of some common names in the macro
>>>> files.
>>>> |
>>>> | But, as it stands, that is a requirement when using Rcpp.
>>>>
>>>> Where?  I can think of one propagated use, which is at the bottom of the
>>>> try/catch structure where we use ::Rf_error.  But the commonly used
>>>> macros
>>>> hide it, and we could/should obviously wrap this.
>>>>
>>>> Otherwise, and especially since the 'Rcpp sugar' initiative took off, I
>>>> don't
>>>> really touch any ::Rf_* myself anymore.  Inside the Rcpp code base, sure.
>>>> But
>>>> not really in user-facing stuff and Rcpp applications.
>>> I didn't make myself clear.  What I meant was that it is not possible
>>> to use asInteger in Rcpp and count on the name being remapped to
>>> Rf_asInteger.
>>>
>>>> | I think of the Rf_ part as more due to the fact that C doesn't have a
>>>> | concept of namespaces so anything in the R API is at the top level
>>>> | namespace leading to some conflicts.
>>>>
>>>> Agreed.  But speaking stylistically, for the same reason that we prefer
>>>> C++
>>>> versions of C header files (eg cstdint over stdint.h, cstdio over
>>>> stdio.h,
>>>> ...) I am with John on the preference for C++ idioms when given a choice.
>>> I suppose I could have just checked whether Rcpp::as<int>    calls
>>> Rf_asInteger.  If so, everything is cool.  Unfortunately, I haven't
>>> been able to find that specialization.
>>>
>> as lives in the inst/include/Rcpp/as.h file, and we have to follow template
>> wizardry:
>>
>> it starts from :
>>
>> template<typename T>  T as( SEXP m_sexp) {
>>         return internal::as<T>( m_sexp, typename
>> traits::r_type_traits<T>::r_category() ) ;
>>     }
>>
>> with T=int, so we end up calling this one:
>>
>> template<typename T>  T as( SEXP x, ::Rcpp::traits::r_type_primitive_tag ) {
>>             if( ::Rf_length(x) != 1 ) throw ::Rcpp::not_compatible(
>> "expecting a single value" ) ;
>>             const int RTYPE = ::Rcpp::traits::r_sexptype_traits<T>::rtype ;
>>             SEXP y = PROTECT( r_cast<RTYPE>(x) );
>>             typedef typename ::Rcpp::traits::storage_type<RTYPE>::type
>> STORAGE;
>>             T res = caster<STORAGE,T>( *r_vector_start<RTYPE,STORAGE>( y ) )
>> ;
>>             UNPROTECT(1) ;
>>             return res ;
>>         }
>>
>>
>> which does the magic. There is no calls to asInteger.
> Which, to me, is the disadvantage.  The asInteger function is brief,
> understandable, flexible and well-tested.  This may look transparent
> to you but not to many others.
We could add another level of indirection and call asInteger, etc ... I 
don't mind either way.

Romain

-- 
Romain Francois
Professional R Enthusiast
http://romainfrancois.blog.free.fr



More information about the Rcpp-devel mailing list