From jason at cs.jhu.edu  Thu Jan 12 14:27:17 2006
From: jason at cs.jhu.edu (Jason Eisner)
Date: Thu, 12 Jan 2006 08:27:17 -0500
Subject: [Rd] problem with replicate and "..." (PR#8472)
In-Reply-To: <x2psmylu3s.fsf@viggo.kubism.ku.dk>
	(Peter Dalgaard's message of "11 Jan 2006 15:25:27 +0100")
References: <20060111114308.0FF342073F@slim.kubism.ku.dk>
	<x2psmylu3s.fsf@viggo.kubism.ku.dk>
Message-ID: <m3bqyh60ga.fsf@tree.cs.jhu.edu>

Yesterday morning, Peter Dalgaard wrote:

> jason at cs.jhu.edu writes:
>
>> I am using R version 2.0.0 (2004-10-04) on Fedora Core 2.
>> 
>> This works correctly:
>> 
>> > foo <- function(x=1,y=2) { c(x,y) }
>> > bar <- function(n,...) c(n,foo(...))
>> > bar(10,3)
>> [1] 10  3  2
>> 
>> But it goes wrong if I replace "c" in bar with "replicate":
>> 
>> > foo <- function(x=1,y=2) { c(x,y) }
>> > bar <- function(n,...) replicate(n,foo(...))
>> > bar(10,3)
>>      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
>> [1,]    0    0    0    0    0    0    0    0    0     0
>> [2,]    2    2    2    2    2    2    2    2    2     2
>> 
>> It is mysterious why x was bound to the apparently arbitrary
>> value 0 while y was left at its default.
>> 
>> The ... arguments to bar seems to be ignored altogether.
>> bar(10), bar(10,x=3), and bar(10,3,4) give the same result.
>> Furthermore, bar(10,extra=3) does not give an error.
>> 
>> Perhaps this mysterious behavior is unavoidable because of 
>> the kind of hack replicate is?
>
> Yes. It is really a wrapper for
>
> sapply(integer(n), eval.parent(substitute(function(...) expr))
>
> Now, integer(n) is n zeroes, and the function that is passed to sapply
> is
>
> Browse[1]> FUN
> function (...)
> foo(...)
> <environment: 0xd82338>
>
> Now, this gets called as FUN(0) and in turn foo(0) which is c(0,2).
>
> So, the short answer is "don't do that", and the long answer is "don't
> do that". If you're adventurous, you could try experimenting with a
> different definition, possibly
>
> sapply(integer(n), eval.parent(substitute(function(...) eval.parent(expr)))
>
> but I'm far from sure that it works...

Peter: thanks for the good explanation.

Perhaps the OFFICIAL replicate function can be fixed as you suggest
above, or by somehow incorporating this workaround:

   bar <- function(n,...) { f <- function() foo(...); 
                            replicate(n,f()) }


If not, then may I suggest that help("replicate") should document the
limitation, and perhaps the workaround as well?  

(The help page does mention that replicate is just a convenience
wrapper, but without a BUGS or LIMITATIONS section as on Unix
manpages, a user might be forgiven for assuming that it actually works
in all cases.  Obviously, a user shouldn't have to understand how a
function is implemented in order to avoid nasty special cases.)

Thanks!  -jason



[Rd] problem with replicate and "..." (PR#8472)
Jason Eisner