From radford at cs.toronto.edu  Sun Mar  1 23:43:45 2015
From: radford at cs.toronto.edu (Radford Neal)
Date: Sun, 1 Mar 2015 17:43:45 -0500
Subject: [Rd] iterated lapply
In-Reply-To: <alpine.DEB.2.02.1503011329120.2327@luke-Latitude>
References: <mailman.17.1425034805.31301.r-devel@r-project.org>
	<20150301171733.GA28691@cs.toronto.edu>
	<alpine.DEB.2.02.1503011329120.2327@luke-Latitude>
Message-ID: <20150301224345.GA2941@cs.toronto.edu>

> 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)

to

  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



[Rd] iterated lapply
Radford Neal