From gavin.simpson at ucl.ac.uk  Fri Nov 18 17:10:20 2011
From: gavin.simpson at ucl.ac.uk (Gavin Simpson)
Date: Fri, 18 Nov 2011 16:10:20 +0000
Subject: [Rd] round() ignores missing arguments if it is used inside
 another function where some arguments are missing.
In-Reply-To: <CAO1zAVaS6YN=7V7tciOpgDA98haDY3wPYyuQt-cxkcsqXGsz=A@mail.gmail.com>
References: <CAO1zAVaS6YN=7V7tciOpgDA98haDY3wPYyuQt-cxkcsqXGsz=A@mail.gmail.com>
Message-ID: <1321632620.17906.68.camel@prometheus.geog.ucl.ac.uk>

On Fri, 2011-11-18 at 16:43 +0100, Joris Meys wrote:
> I have stumbled across some behaviour in R that I really can't place,
> and that makes coding a bit tricky. I know that I can work around it
> when explicitly checking for missing arguments, but still...
> I have two functions. I have a first function based on paste
> 
>     fun1 <- function(x,y){
>       print(missing(y))
>       paste(x,'X',sep=y)
>     }
> 
> If I try this function without specifying `y`, I get the (expected)
> error message:
> 
>     > fun1(letters[1:6])
>     [1] TRUE
>     Error in paste(x, "X", sep = y) :
>       argument "y" is missing, with no default
> 
> The second one with round :
>     fun2 <- function(x,y){      print(missing(y))      round(x,digits=y)    }
> If I try this function without specifying `y`, it works unexpectedly
> whereas it shouldn't :
>     > fun2(100.1)    [1] TRUE    [1] 100

round() is implemented as:

> round
function (x, digits = 0)  .Primitive("round")

using the .Primitive means of calling C code. `?.Primitve` refers you to
the R Internals manual, which basically states that how the compiled
functions should be called and number of arguments etc is stored in a
table. This table is given here:

http://svn.r-project.org/R/trunk/src/main/names.c

The relevant part of which is:

/* printname	c-entry		offset	eval	arity	pp-kind	     precedence	rightassoc
 * ---------	-------		------	----	-----	-------      ----------	----------*/
....
/* Mathematical Functions */
/* primitives: these are group generic and so need to eval args (possibly internally) */
{"round",	do_Math2,	10001,	0,	-1,	{PP_FUNCALL, PREC_FN,	0}},


the eval column indicates features of how arguments are evaluated and
what have you. A value of 0 equates to 000 and the last 0 indicates
whether arguments are to be evaluated with 0 indicating no evaluation
and 1 evaluation.

round is indicated to not evaluate its arguments. I don't follow the C
code well enough to know if it should be catching the missing argument
further on - it must be because it is falling back to the default, but
the above explains that the not evaluating arguments is intended.

G

> In my view, fun1 should definitely give the error message as well, as
> it is not intended to have a default behaviour when y is missing.
> Still, the round() function ignores the fact y is missing. Is this by
> design, is there a check missing in round, or is something else going
> on that I am overlooking?
> 
> Cheers
> Joris
> > sessionInfo()
> R version 2.14.0 (2011-10-31)
> Platform: i386-pc-mingw32/i386 (32-bit)
> 
> locale:
> [1] LC_COLLATE=English_United Kingdom.1252
> [2] LC_CTYPE=English_United Kingdom.1252
> [3] LC_MONETARY=English_United Kingdom.1252
> [4] LC_NUMERIC=C
> [5] LC_TIME=English_United Kingdom.1252
> 
> attached base packages:
> [1] stats     graphics  grDevices utils     datasets  methods
> [7] base
> 
> loaded via a namespace (and not attached):
> [1] tools_2.14.0
> 

-- 
%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%
 Dr. Gavin Simpson             [t] +44 (0)20 7679 0522
 ECRC, UCL Geography,          [f] +44 (0)20 7679 0565
 Pearson Building,             [e] gavin.simpsonATNOSPAMucl.ac.uk
 Gower Street, London          [w] http://www.ucl.ac.uk/~ucfagls/
 UK. WC1E 6BT.                 [w] http://www.freshwaters.org.uk
%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%



[Rd] round() ignores missing arguments if it is used inside another function where some arguments are missing.
Gavin Simpson