3

I'm having trouble calling match.call() from a C++ function. In the example below, the match_call() C++ function fails at simply forwarding its arguments to match.call(). What am I missing?

match_call <-
  Rcpp::cppFunction(
    '
      SEXP match_call(SEXP definition, SEXP call) {
        Function m("match.call", R_BaseEnv);
        return m(definition, call);
      }
    ')

match.call(function(a = 1, b = 2){}, quote(fun(b = 4, 3)))
## fun(a = 3, b = 4)
match_call(function(a = 1, b = 2){}, quote(fun(b = 4, 3)))
## error: could not find function "fun"

As suggested by @nicola, adding a quote() helps:

        return m(definition, Rf_lang2(R_QuoteSymbol, call));

This works, but doesn't explain the mechanisms.

krlmlr
  • 25,056
  • 14
  • 120
  • 217
  • Seems like that a call to `eval` is made on the arguments when you are calling R functions from C++. For instance, `match_call(function(a = 1, b = 2){}, quote(quote(fun(b = 4, 3))))` works, since the (implicit) `eval` call just cancels the first `quote`. – nicola Dec 07 '16 at 14:29
  • You can wrap the Rcpp function with an R function: `match_callR<-function(definition,call) match_call(definition,substitute(call))` to obtain the desired output. – nicola Dec 07 '16 at 14:36
  • @nicola: Thanks. I suspected this, but what's the reason for this behavior? You mentioned an "implicit eval()". – krlmlr Dec 07 '16 at 14:58
  • Can't be sure, but I think that in the C++ construct `f(a,b)` where `f` is an R function and `a` and `b` are the arguments, `a` and `b` are implicitly `eval`uated in order to make the call to the function. Hope that someone more competent (Dirk Eddelbuettel, the author of `Rcpp`, is very active on SO) might jump in and give a correct answer. – nicola Dec 07 '16 at 15:12
  • 2
    `Rcpp::Function` is one of several ways to get to it; it may enforce an early `eval()`. Maybe try `Rcpp::Language` -- page 9 of the 'Rcpp Introduction' had that as an example for over half a decade. – Dirk Eddelbuettel Dec 07 '16 at 15:13
  • 2
    Returning something like `return(Rf_lang3(Rf_install("match.call"), definition, call));` from `match_call` shows how it differs from the equivalent `quote( match.call(function(a = 1, b = 2){}, quote(fun(b = 4, 3))) )` on that the second argument is evaluated. I guess [here](http://stackoverflow.com/questions/19686892/passing-unevaluated-expressions-to-c-c) is a similar discussion. – alexis_laz Dec 07 '16 at 15:38
  • Excellent catch @alexis_laz. – Dirk Eddelbuettel Dec 07 '16 at 16:37

0 Answers0