On Sat, Dec 25, 2010 at 5:02 PM, Dominick Samperi <djsamp...@gmail.com> wrote: > > > On Sat, Dec 25, 2010 at 4:08 PM, Gabor Grothendieck > <ggrothendi...@gmail.com> wrote: >> >> On Sat, Dec 25, 2010 at 3:58 PM, Dominick Samperi <djsamp...@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 _______________________________________________ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel