Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where do absent dots (`...`) get processed?

Tags:

arguments

r

If we view the body of a function that has dots ... in its argument list, we can usually find the function that receives those dots arguments.

For example, we can see in the body of sapply() that the dots arguments are passed through to lapply().

sapply
# function (X, FUN, ..., simplify = TRUE, USE.NAMES = TRUE) 
# {
#     FUN <- match.fun(FUN)
#     answer <- lapply(X = X, FUN = FUN, ...)
#     ## rest of function body
# }
# <bytecode: 0x000000000e05f0b0>
# environment: namespace:base>

However, in lapply(), there are dots ... in the argument list but not in the function body.

lapply
# function (X, FUN, ...) 
# {
#     FUN <- match.fun(FUN)
#     if (!is.vector(X) || is.object(X)) 
#         X <- as.list(X)
#     .Internal(lapply(X, FUN))
# }
# <bytecode: 0x0000000009414f08>
# <environment: namespace:base>

So where do the dots ... arguments in lapply() get processed? What/where are they passed to? We cannot pass them to match.fun(). I presume they are passed into .Internal() but I don't see any reason for this to work when I don't see them passed into any function in the function body.

like image 882
Rich Scriven Avatar asked Aug 16 '15 00:08

Rich Scriven


1 Answers

They're not explicitly passed to .Internal, but I believe they're available to do_lapply (in src/main/apply.c) via dynamic scope. The scoping rules may be slightly different than usual, since .Internal is a primitive function.

You can see that ... (R_DotsSymbol) is added to the function call lapply creates, so they're available to the function call on each list element. tmp is roughly equivalent to X[[i]] and R_fcall is roughly equivalent to FUN(X[[i]], ...).

SEXP tmp = PROTECT(LCONS(R_Bracket2Symbol,
        LCONS(X, LCONS(isym, R_NilValue))));
SEXP R_fcall = PROTECT(LCONS(FUN,
             LCONS(tmp, LCONS(R_DotsSymbol, R_NilValue))));
like image 140
Joshua Ulrich Avatar answered Oct 17 '22 00:10

Joshua Ulrich