[Rd] eapply weirdness/bug

Luke Tierney luke at stat.uiowa.edu
Fri Feb 18 15:44:06 CET 2005

On Fri, 18 Feb 2005, Peter Dalgaard wrote:

> <Mark.Bravington at csiro.au> writes:
>> The following looks like an 'eapply' bug to me:
>> t/subtest> e <- new.env()
>> t/subtest> e$tempo <- quote( 1+'hi')
>> t/subtest> lapply( ls( e), function( x) length( get( x,e)))
>> [[1]]
>> [1] 3
>> # seems reasonable-- e$tempo is a 'call' object of length 3
>> t/subtest> eapply( e, length)
>> Error in 1 + "hi" : non-numeric argument to binary operator
>> t/subtest> eapply( e, length)
>> t/subtest> traceback()
>> 1: eapply(e, length)
>> For some reason 'eapply' seems to *evaluate* objects of mode 'call' (it
>> happened with every call-mode object I tried). This shouldn't happen--
>> or should it?
> It's probably related to the fact that
>> eval(substitute(length(x),list(x=e$tempo)))
> Error in 1 + "hi" : non-numeric argument to binary operator
> I.e., you cannot construct calls with a mode call argument by
> substituting the value of the mode call object. (Got that? Point is
> that the substitute returns quote(length(1+"hi")))
> It is not clear to me that there is a nice way of fixing this. You
> probably need to construct calls of the form FUN(env$var) -- I suspect
> that with(env, FUN(var)) or eval(FUN(var), env) would looking for
> trouble. Hmm, then again, maybe it could work if FUN gets inserted as
> an anonymous function...

Looks broken to me:

     > e<-new.env()
     > assign("x",quote(y),e)
     > eapply(e, function(x) x)
     Error in FUN(y, ...) : Object "y" not found

in contrast to

     > lapply(list(quote(y)),function(x) x)

looks like eapply has an extra eval in the code.  It does because the
code creates a call of the form


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


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

and evaluating that, but we are not getting this.  Direct use of this
would be less efficient that the current approach, but using


as the constructed call should do the trick.

[There seem to be a few other unnecessary eval's in cmputing the arguments
but I haven't thought this through yet]


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