[Rcpp-devel] Checking for a promise

Gabor Grothendieck ggrothendieck at gmail.com
Sat Dec 25 23:22:17 CET 2010


On Sat, Dec 25, 2010 at 5:02 PM, Dominick Samperi <djsamperi at gmail.com> wrote:
>
>
> On Sat, Dec 25, 2010 at 4:08 PM, Gabor Grothendieck
> <ggrothendieck at gmail.com> wrote:
>>
>> On Sat, Dec 25, 2010 at 3:58 PM, Dominick Samperi <djsamperi at gmail.com>
>> wrote:
>> > Using .Call appears to force the promise:
>> >
>> > msg="old"
>> > delayedAssign("x",msg)
>> > msg="new"
>> > .Call('sexpType',x) # promise triggered here, returns 16
>> > msg="even newer" # will not change already fired promise
>> > .Call('sexpType',x) # returns 16
>> > y = x
>> > y # "new" (not "even newer")
>> >
>> > Here's sexpType:
>> >
>> > RcppExport SEXP sexpType(SEXP x_) {
>> >     return Rcpp::wrap(TYPEOF(x_));
>> > }
>> >
>> > The type returned is 16 here (STRSXP). If numbers were
>> > assigned to msg instead 14 would be returned (REALSXP).
>> >
>>
>> Note that the first attempt I posted tried to get around that by
>> passing the environment and the name of the variable in the
>> environment so that the object would not itself be passed yet it did
>> not work either.  Here is a slight variation:
>
> Yes, I tired your variant (just passing the environment) but it
> still doesn't work. Here is the explanation: Rcpp currently
> implements e[] (i.e., operator [] for Environment) via get(),
> and when the variable is a promise it evaluates, effectively
> forcing the promise. There is a Rcpp::Promise class, but it is
> probably work in progress because it is not exposed.
>
>>
>> > library(Rcpp)
>> > library(inline)
>> > f <- cxxfunction(signature(env="environment", nm = "character"),
>> +        body=' Environment e(env);
>> +           std::string s = as<std::string>(nm);
>> +           return wrap(TYPEOF (e[s])); ',
>> +        plugin="Rcpp")
>> >
>> > # create promise
>> > delayedAssign("prom", 3)
>> >
>> > # want it to return 5 but it returns 14
>> > f(.GlobalEnv, "prom")
>> [1] 14

It seems that there are no facilities for this in Rcpp -- at least I
haven't found them.  It seems one has to go one level lower to do
this.  The code below works.  It passes an environment and name and
returns the type code.  I think this sort of functionality was
intentionally left out of R itself and if one were just trying to
emulate R then I can understand it not being there but since Rcpp is
intended for performance it might be a good idea to give this sort of
access to promises without forcing the program to use the lower level
facilities.

The main functions that would be nice would be:
- to determine if an object is a promise
- to extract, set and replace its components (i.e. the expression and
the environment).
- also the ability to copy a promise from one environment to another
without forcing it

library(Rcpp)
library(inline)
f <- cxxfunction(signature(env="environment", nm = "character"),
       body=' Environment e(env);
          std::string s = as<std::string>(nm);
          SEXP res = Rf_findVarInFrame( e, Rf_install(s.c_str())  ) ;
          if( res == R_UnboundValue ) return R_NilValue ;
          return wrap(TYPEOF (res)); ',
       plugin="Rcpp")

# create promise
delayedAssign("prom", 3)

# returns 5 which is the code for a promise
f(.GlobalEnv, "prom")

-- 
Statistics & Software Consulting
GKX Group, GKX Associates Inc.
tel: 1-877-GKX-GROUP
email: ggrothendieck at gmail.com


More information about the Rcpp-devel mailing list