6

Why there is no error reported when b is not supplied but required inside the function? Thanks!

f2 <- function(a,b) {a[b]}; f2(a=rep(1, 2))

I understand that there is no error in this function:

f <- function(x) {
  10
}
f(stop("This is an error!"))

due to lazy evaluation But this

f <- function(x) {
  force(x)
  10
}
f(stop("This is an error!"))

or this

f <- function(x) {
  x
  10
}
f(stop("This is an error!"))

will produce an error. Because in both cases x is used within the function. Both the above two examples are from http://adv-r.had.co.nz/Functions.html. Since b is also used within f2, should it be necessary to add force inside f2? Thanks!

kevin
  • 164
  • 5
  • 1
    Simpler version, same issue - `f2 – thelatemail Apr 26 '18 at 01:59
  • 2
    I'm guessing this is some lazy evaluation quirk that I don't fully understand since if you `debug(f2)` you can see that `b` is returned from `ls()` inside the function's environment. `f2 – thelatemail Apr 26 '18 at 02:16
  • But I think in the link above, the original function f is not **used**. https://stackoverflow.com/questions/29733257/can-you-more-clearly-explain-lazy-evaluation-in-r-function-operators – kevin Apr 26 '18 at 02:36

2 Answers2

6

x[b] returns (a duplicate of) x if b is missing. From the R source:

static SEXP VectorSubset(SEXP x, SEXP s, SEXP call)
{
    R_xlen_t stretch = 1;
    SEXP indx, result, attrib, nattrib;

    if (s == R_MissingArg) return duplicate(x);

https://github.com/wch/r-source/blob/ec2e89f38a208ab02449b706e13f278409eff16c/src/main/subset.c#L169

From the documentation, in which 'empty' means 'missing', not NULL:

An empty index selects all values: this is most often used to replace all the entries but keep the attributes.

Hugh
  • 14,547
  • 9
  • 54
  • 94
3

It has to do with the [ function, not lazy evaluation. You'll get an error if you do the following:

f3 <- function(a,b) {a+b}; f3(a = 1)

Note that since b is not defined, R is interpreting it as if it didn't exist. Try doing:

a <- c(1,1) 
a[]

It seems that the subsetting function ( `[` ) actually takes ... as a parameter. I.e., specifying indices to subset are optional.

David Klotz
  • 2,316
  • 1
  • 6
  • 15