From luke at stat.uiowa.edu  Fri Feb 18 15:44:06 2005
From: luke at stat.uiowa.edu (Luke Tierney)
Date: Fri Feb 18 15:44:42 2005
Subject: [Rd] eapply weirdness/bug
In-Reply-To: <x2vf8q5k3a.fsf@biostat.ku.dk>
References: <4D99275E380CA94F998977EDACE548DC074AAC@extas2-hba.tas.csiro.au>
	<x2vf8q5k3a.fsf@biostat.ku.dk>
Message-ID: <Pine.LNX.4.61.0502180821170.3177@itasca2.stat.uiowa.edu>

On Fri, 18 Feb 2005, Peter Dalgaard wrote:

> <Mark.Bravington@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)
     [[1]]
     y

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

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.

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

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@stat.uiowa.edu
Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu


[Rd] eapply weirdness/bug
Luke Tierney