Skip to content

Curious behavior of $ and lapply

3 messages · Stavros Macrakis, Kevin Ushey

#
`lapply` basically takes its call and massages into calls of the following form:

    FUN(X[[1L]], ...)
    FUN(X[[2L]], ...)
    ... <up to length of X>

that get evaluated in the appropriate environment.

For `lapply(list(list(a=3,b=4)),"$","b")`, you can imagine that a
function `FUN` of the form:

    FUN <- function(x, ...) "$"(x, ...)

is being generated, and then evaluated as

    FUN(list(list(a=3, b=4))[[1L]], "b") ## returns NULL

and I can only guess that the non-standard evaluation of `$` is not
interpreting `...` as you expect.

Moral of the story -- lapply does non-standard evaluation, and does
not compose nicely with other functions performing non-standard
evaluation. This is discussed a bit in the Note: section of `?lapply`.
Copied from there (emphasis mine):

For historical reasons, the calls created by lapply are unevaluated,
and code has been written (e.g. bquote) that relies on this. This
means that the recorded call is always of the form FUN(X[[i]], ...),
with i replaced by the current (integer or double) index. This is not
normally a problem, but it can be if FUN uses sys.call or match.call
or if it __is a primitive function that makes use of the call__. This
means that it is often safer to call primitive functions with a
wrapper, so that e.g. lapply(ll, function(x) is.numeric(x)) is
required to ensure that method dispatch for is.numeric occurs
correctly.

Cheers,
Kevin


On Mon, Jun 23, 2014 at 3:04 PM, Stavros Macrakis (??????? ????????)
<macrakis at alum.mit.edu> wrote: