[Rd] iterated lapply

Radford Neal radford at cs.toronto.edu
Sun Mar 1 23:43:45 CET 2015

> There are other instances, such as Reduce where there is a bug
> report pending that amounts to the same issue.  Performing surgery on
> expressions and calling eval is not good practice at the R level and
> probably not a good idea at the C level either.  It is worth thinking
> this through carefully before a adopting a solution, which is what we
> will be doing.

Surgery on expressions is what lapply does at the moment.  My change
makes it no longer do that.  

There is a general problem that lazy evaluation can have the effect
of making the internal details of how an R function like "apply" is
implemented leak into its semantics.  That's what's going on with
the Reduce bug (16093) too.  

I think one can avoid this by defining the following function for
calling a function with evaluation of arguments forced (ie, lazy
evaluation disabled):

  call_forced <- function (f, ...) { list (...); f (...) }

(Of course, for speed one could make this a primitive function, which
wouldn't actually build a list.)

Then the critical code in Reduce could be changed from

  for (i in rev(ind)) init <- f(x[[i]], init)


  for (i in rev(ind)) init <- call_forced (f, x[[i]], init)

If one had a primitive (ie, fast) call_forced, a similar technique
might be better than the one I presented for fixing "apply" (cleaner,
and perhaps slightly faster).  I don't see how it helps for functions
like lapply that are written in C, however (where help isn't needed,
since there's nothing wrong with the mod in my previous message).

   Radford Neal

More information about the R-devel mailing list