[Rd] eapply weirdness/bug

Luke Tierney luke at stat.uiowa.edu
Fri Feb 18 18:00:00 CET 2005


On Fri, 18 Feb 2005, Peter Dalgaard wrote:

> Luke Tierney <luke at stat.uiowa.edu> writes:
>
>> looks like eapply has an extra eval in the code.  It does because the
>> code creates a call of the form
>>
>>      FUN(<value>)
>>
>> with the literal value in place and then calls eval on this, which
>> results in calling eval on value.  The internal lapply in contrast
>> creates a call of the form
>>
>>      FUN(<list>[[<index>]])
>>
>> and evals that.  This causes the literal <list> and <index> values to
>> be evaluated, which is OK since they are guaranteed to be a list
>> (generic vector) and integer vector and so evaluate to themselves, and
>> the call to [ is then evaluated, returning what is in the list at the
>> appropriate index and passing that, without further evluation, to FUN.
>> The semantics we want in eapply is I think equivalent to creating
>>
>>      FUN(get(<name>, <envir>))
>
> Or, as I was suggesting,
>
> eval(substitute(F(x), list(F=FUN,x=as.name(e)), envir)

Well, you know my view of adding more nonstandard evaluation.  Any
explicit use of eval is almost always a Really Bad Idea, and in most
of the remaining cases it is a bad idea.  In any cases that still
remain it should be avoinded if at all possible. And if it seems not
possible then it is best to put the problem down for a while and think
a bit more....

>> and evaluating that, but we are not getting this.  Direct use of this
>> would be less efficient that the current approach, but using
>>
>>      FUN(quote(<value>))
>>
>> as the constructed call should do the trick.
>
> You have to be careful only to do this if the value is of mode "call",
> I think. Or is quote always a no-op in the other cases?

quote is fine--it always returns the object that appears as the
argument in the call.  For quote expressions created as the result of
parsing that will be a somewhat limited set of things, but for quote
calls created programmatically it can be anything.

> I'm getting a bit fond of the the solution that I had because it will
> also work if the FUN uses deparse(substitute(....)) constructions, and
> once you're at the level of constructing calls via LCONS() it isn't
> really inefficient either. Extra arguments could be a bit of a bother
> though. (What happens to those currently?? The function doesn't seem to
> pass them to .Internal.)

I believe none of our apply family of functions can be expected to do
anything very useful in situations that require nonstandard evaluation
based on the call context.  I don't beieve we explicitly document what
is supposed to happen here (and I'm not sure we want to at least at
this point: this is the sort of thing where leaving it undefined gives
alternate implementations, such as one based on compilation, some room
to work with).  But it might be worth thinking about narrowing
variability a little.  A somewhat related issue is that we don't have
a completely standard mechanism of calling an function from within C
code--we do it by creating and eval'ing (in C) a call expression, but
there may be some slight variations in the way it is done in different
places that we might want to think about at some point.

For this specific case though, I _think_ the semantics we want is this:

     eapply1 <- function(env, FUN, ..., all.names = FALSE) {
 	FUN <- match.fun(FUN)
 	lapply(.Internal(env2list(env, all.names)), FUN, ...)
     }

Not passing the ... in the current implementation is, I think, an
oversight, as is the extra evaluation that occurs.  Given that lapply
is already internal I'm not sure there really is very much benefit in
having the internal eapply.  If not I'd prefer to replace it by
something like this; if there are reasons for keeping the .Internal we
can work on replicating these semantics as closely as possible.  I
think Robert is the one who would know the issues.

luke


-- 
Luke Tierney
University of Iowa                  Phone:             319-335-3386
Department of Statistics and        Fax:               319-335-3017
    Actuarial Science
241 Schaeffer Hall                  email:      luke at stat.uiowa.edu
Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu



More information about the R-devel mailing list