From btyner at gmail.com  Wed Feb 25 23:35:01 2015
From: btyner at gmail.com (Benjamin Tyner)
Date: Wed, 25 Feb 2015 17:35:01 -0500
Subject: [Rd] iterated lapply
In-Reply-To: <4346B4DF-036F-4594-96C0-F8D3121427D0@gmail.com>
References: <4346B4DF-036F-4594-96C0-F8D3121427D0@gmail.com>
Message-ID: <54EE4E15.4000506@gmail.com>

Actually, it depends on the number of cores:

    > fun1 <- function(c){function(i){c*i}}
    > fun2 <- function(f) f(2)
    > sapply(mclapply(1:4, fun1, mc.cores=1L), fun2)
    [1] 8 8 8 8
    > sapply(mclapply(1:4, fun1, mc.cores=2L), fun2)
    [1] 6 8 6 8
    > sapply(mclapply(1:4, fun1, mc.cores=4L), fun2)
    [1] 2 4 6 8

> >/ On Feb 24, 2015, at 10:50 AM, <luke-tierney at uiowa.edu <https://stat.ethz.ch/mailman/listinfo/r-devel>> wrote:
> />/ 
> />/ The documentation is not specific enough on the indented semantics in
> />/ this situation to consider this a bug. The original R-level
> />/ implementation of lapply was
> />/ 
> />/    lapply <- function(X, FUN, ...) {
> />/        FUN <- match.fun(FUN)
> />/        if (!is.list(X))
> />/        X <- as.list(X)
> />/        rval <- vector("list", length(X))
> />/        for(i in seq(along = X))
> />/        rval[i] <- list(FUN(X[[i]], ...))
> />/        names(rval) <- names(X)           # keep `names' !
> />/        return(rval)
> />/    }
> />/ 
> />/ and the current internal implementation is consistent with this. With
> />/ a loop like this lazy evaluation and binding assignment interact in
> />/ this way; the force() function was introduced to help with this.
> />/ 
> />/ That said, the expression FUN(X[[i]], ...) could be replaced by
> />/ 
> />/    local({
> />/        i <- i
> />/        list(FUN(X[[i]], ...)
> />/    })
> />/ 
> />/ which would produce the more desirable result
> />/ 
> />/    > sapply(test, function(myfn) myfn(2))
> />/    [1] 2 4 6 8
> />/ 
> /
> Would the same semantics be applied to parallel::mclapply and friends?
>
> sapply(lapply(1:4, function(c){function(i){c*i}}), function(f) f(2))
>
> # [1] 8 8 8 8
>
> sapply(mclapply(1:4, function(c){function(i){c*i}}), function(f) f(2))
>
> # [1] 6 8 6 8
>
> I understand why they differ, but making mclapply easier for 'drop-in' parallelism might be a good thing. 
>
> Michael



[Rd] iterated lapply
Benjamin Tyner