Due to lazy evaluation (#13861 and #14004) and re-assignment in Reduce, reducing on functions makes them capture themselves instead of the actual argument. Try a simple function composition: f <- function(x) x f1 <- function(h) { function(x) paste("f1", h(x)) } rf <- Reduce(function(f, h) f(h), list(f1), init = identity, right = T) rf("start") ## -> Error: evaluation nested too deeply: infinite recursion Second order `f` captures itself instead of the argument `h` on recursive assignment. Simple example: f <- f1(f) f("start") ## -> Error: evaluation nested too deeply: infinite recursion identical(f, environment(f)$h) ## [1] TRUE It works fine with: f2 <- f1(f) f2("start") In Reduce it's on line 23: ╭──────── #23 ─ Reduce.R ── │ if (right) { │ for (i in rev(ind)) init <- f(x[[i]], init) │ } ╰──────── #25 ─ Now that I know the problem, I can easily fix it by `force`, but it takes a while to figure out what's going on. --- BTW, Would be really nice to have a Compose function in the `funprog` set.

Resolved in R-devel by r68010.

Did r68010 change the semantics in particular with regard to unevaluated expressions? Compare under R < 3.2, > str(lapply(list(a=10,b=10,c=10), function(x) substitute(x))) List of 3 $ a: language X[[1L]] $ b: language X[[2L]] $ c: language X[[3L]] versus under R >= 3.2, > str(lapply(list(a=10,b=10,c=10), function(x) substitute(x))) List of 3 $ a: language X[[i]] $ b: language X[[i]] $ c: language X[[i]]

Yes - now more consistent with others, e.g. > str(apply(matrix(1:2), 1,function(x) substitute(x))) List of 2 $ : language newX[, i] $ : language newX[, i] in both R versions.

Thanks Luke. Is there a way to mimic the prior lapply functionality? I tried using forceAndCall but with no success; per the help page, it only works with closures (whereas substitute is primitive).