Skip to content
Prev 40619 / 63424 Next

doMC - compiler - concatenate an expression vector into a single expression?

Hi,

this post is about foreach operators, the compiler package and the last 
update of doMC that includes support for the compiler functionality.

I am using a home-made %dopar%-like operator that adds some custom 
expression to be executed before the foreach loop expression itself (see 
sample code below).
It used to work perfectly with doMC 1.2.1, but with the introduction of 
the compiler functionality, things do not work properly.
The change in the doMC package consists in evaluating a compiled 
expression instead of the original R expression:

# from doMC:::doMC ...
c.expr <- comp(expr, env = envir, options = list(suppressUndefined = TRUE))

and for R >= 2.13.0 comp is defined as compiler::compile:
function (e, env = .GlobalEnv, options = NULL)
{
     cenv <- makeCenv(env)
     cntxt <- make.toplevelContext(cenv, options)
     cntxt$env <- addCenvVars(cenv, findLocals(e, cntxt))
     genCode(e, cntxt)
}
<environment: namespace:compiler>

My guess is that the function findLocals or genCode can not handle a 
2-length expression vector.

Maybe somebody who knows the internals of these functions could explain 
better this behaviour?
How can I concatenate two expressions into a single one?

Thank you,
Renaud


##################################################
# Sample code
##################################################

`%dopar2%` <- function(obj, ex){

     # append custom code to the expression
     ex <- c(expression({ a <- i; message("Custom ", a);}), substitute(ex))

     # call the standard %dopar% operator
     do.call(`%dopar%`, list(obj, ex), envir=parent.frame() )
}
res <- foreach(i=1:3) %dopar2% { print(i); i*2; }
res


#########################
# Output with doSEQ or doMC 1.2.1
#########################
Custom 1
[1] 1
Custom 2
[1] 2
Custom 3
[1] 3
 > res
[[1]]
[1] 2

[[2]]
[1] 4

[[3]]
[1] 6


#########################
# Output with doMC 1.2.2
#########################

[[1]]
expression({
     a <- i
     message("Custom ", a)
}, {
     print(i)
     i * 2
})

[[2]]
expression({
     a <- i
     message("Custom ", a)
}, {
     print(i)
     i * 2
})

[[3]]
expression({
     a <- i
     message("Custom ", a)
}, {
     print(i)
     i * 2
})