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 ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel