From luke@stat.umn.edu  Fri May  9 15:52:13 1997
From: luke@stat.umn.edu (Luke Tierney)
Date: Fri, 9 May 1997 09:52:13 -0500 (CDT)
Subject: R-alpha: R-0.49 / S-plus: "default argument evaluation" bugs and woes
In-Reply-To: <9705091338.AA02212@> from "Martin Maechler" at May 9, 97 03:38:33 pm
Message-ID: <9705091452.AA24334@nokomis.stat.umn.edu>

Martin Maechler wrote:
> 
> 
> There is a problem with  'default argument evaluation'
> when I use an existing function name as argument name :
> 
> sintest <- function(x, y = 2, sin= sin(pi/4))
> {
>   ## Purpose: Test of   "default argument evaluation"
>   ## -------- Fails for  R-0.49.  Martin Maechler, Date:  9 May 97.
>   c(x=x, y=y, sin=sin)
> }
> 
> ## R-0.49:
> R> sintest(1)
> ##> Error in sintest(1) : recursive default argument reference
> 
> ## S-plus 3.4  (being 100% ok):
> S> sintest(1)
>   x y       sin 
>   1 2 0.7071068
>  Warning messages:
>    looking for function "sin", ignored local non-function in: sintest(1)
> 
> -------------------------------------------------------
> The following shows bugs, both in R and S:
> 
> sintest2 <- function(x ,y = 2)
> {
>   ## Purpose: Test of   "default argument evaluation"
>   ## -------- Fails for  S-plus 3.4.  Martin Maechler, Date:  9 May 97.
>   c(x=x, y=y, sin=sin)
> }
> 
> R> sintest2(1)
> [[1]]
> [1] 1
> 
> [[2]]
> [1] 2
> 
> [[3]]
> <primitive: sin>
> 

For better or worse, S and R allow default expressions to contain
references variables that are (or rather may be) created in the
function body, so (in R and Splus)

> x<-1
> f<-function(a,b=x) { if (a) x<-2; b}
> f()
Error: Argument "a" is missing, with no default
> f(T)
[1] 2
> f(F)
[1] 1

More traditional lexical scoping would make the reference to x in the
default always be global, but lots of code would break. I think we're
stuck with this behavior as a corollary to the way S wants default
arguments to work.

Actually S is a bit inconsistent in its error message -- if you have a
non-function argument it gives the same message as R,

> g<-function(x=x) x
>g()
Error in g(): Recursive occurrence of default argument "x"
Dumped

Also in R's lexical scoping you probably do want the argument name to
shadow any outer definitions if you want to be able to define default
arguments that are recursive functions, e.g.

> g<-function(n, nfac=function(x) { if (x <= 1) 1 else nfac(x-1)*x }) nfac(n);
> g(6)
[1] 720

-- 
Luke Tierney
University of Minnesota                      Phone:           612-625-7843
School of Statistics                         Fax:             612-624-8868
206 Church Street                            email:      luke@stat.umn.edu
Minneapolis, MN 55455 USA                    WWW:  http://www.stat.umn.edu
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-devel-request@stat.math.ethz.ch
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-


R-alpha: R-0.49 / S-plus: "default argument evaluation" bugs and woes
Luke Tierney