Berwin A Turlach
2005-Dec-02 10:31 UTC
[Rd] Enlightenment sought and a possible buglet in vector.Rd
Dear all, First, I recently had reasons to read the help page of as.vector() and noticed in the example section the following example: x <- c(a = 1, b = 2) is.vector(x) as.vector(x) all.equal(x, as.vector(x)) ## FALSE However, in all versions of R in which I executed this example, the all.equal command returned TRUE which suggest that either the comment in the help file is wrong or the all.equal/as.vector combination does not work as intended in this case. For the former case, I attach below a patch which would fix vector.Rd. Secondly, I stumbled across two behaviours of R that I cannot explain but would like to know why R behaves as it does. But since I expect the explanations to be quite technical, I though that r-devel is the more appropriate list to ask on than r-help. The first example is the following: > f1 function(){ par.def <- par(no.readonly=TRUE) on.exit(par(par.def)) tt <- sys.on.exit() print(tt) str(tt) invisible() } > f1() par(par.def) language par(par.def) > f2 function(){ par.def <- par(no.readonly=TRUE) on.exit(par(par.def)) print(tt <- sys.on.exit()) str(tt) invisible() } > f2() NULL NULL I found in the R language definition manual the passage that discourages users of assigning objects within function calls since it is not guaranteed that the assignment is ever made because of R's lazy evaluation model. But this does not seem to explain the above behaviour since the argument to print is evaluated. If I replace sys.on.exit() with, say, ls() in both functions, then they produce the same output (and the output that I expect). Why does f2() not work with sys.on.exit()? The second behaviour that I cannot explain was produced by code written by somebody else, namely: > foo function(x){ z <- x/4 while( abs(z*z*z-x) > 1e-10 ){ z <- (2*z+x/z^2)/3 } } The documentation of function() says that if "the end of a function is reached without calling 'return', the value of the last evaluated expression is returned." And this seems to happen in this case: > z <- foo(3) > z [1] 1.442250 However, my understanding was always that the return value of a function issued on the command line will be printed; except, of course, if invisible() is used to return the value. This is not the case for the above function: > foo(3) produces no output. And this had us stunned for some time. On the other hand: > ( foo(3) ) [1] 1.442250 So my question is why does R, when "foo(3)" is issued on the command line, not print the value returned by the function? Any enlightening comments are highly appreciated. Cheers, Berwin -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: R-patch Url: https://stat.ethz.ch/pipermail/r-devel/attachments/20051202/5340f532/R-patch.pl
Prof Brian Ripley
2005-Dec-02 10:46 UTC
[Rd] Enlightenment sought and a possible buglet in vector.Rd
On Fri, 2 Dec 2005, Berwin A Turlach wrote: [...]> The second behaviour that I cannot explain was produced by code > written by somebody else, namely: > > > foo > function(x){ > z <- x/4 > while( abs(z*z*z-x) > 1e-10 ){ > z <- (2*z+x/z^2)/3 > } > } > > The documentation of function() says that if "the end of a function is > reached without calling 'return', the value of the last evaluated > expression is returned." And this seems to happen in this case:Yes, but that value can be returned with R_Visible set to 0, by calling invisible() _or otherwise_.> > z <- foo(3) > > z > [1] 1.442250 > > However, my understanding was always that the return value of a > function issued on the command line will be printed; except, of > course, if invisible() is used to return the value. This is not the > case for the above function: > > > foo(3) > > produces no output. And this had us stunned for some time. On the > other hand: > > > ( foo(3) ) > [1] 1.442250 > > So my question is why does R, when "foo(3)" is issued on the command > line, not print the value returned by the function?R does not print the value of a while() loop. Try x <-3 z <- x/4 while( abs(z*z*z-x) > 1e-10 ){ z <- (2*z+x/z^2)/3 } .Last.value and you are seeing no different. (Look up the code of do_while for why.) -- Brian D. Ripley, ripley at stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UK Fax: +44 1865 272595
Prof Brian Ripley
2005-Dec-02 11:37 UTC
[Rd] Enlightenment sought and a possible buglet in vector.Rd
On Fri, 2 Dec 2005, Berwin A Turlach wrote:> Secondly, I stumbled across two behaviours of R that I cannot explain > but would like to know why R behaves as it does. But since I expect > the explanations to be quite technical, I though that r-devel is the > more appropriate list to ask on than r-help. > > The first example is the following: > > > f1 > function(){ > par.def <- par(no.readonly=TRUE) > on.exit(par(par.def)) > tt <- sys.on.exit() > print(tt) > str(tt) > invisible() > } > > f1() > par(par.def) > language par(par.def) > > f2 > function(){ > par.def <- par(no.readonly=TRUE) > on.exit(par(par.def)) > print(tt <- sys.on.exit()) > str(tt) > invisible() > } > > f2() > NULL > NULL > > I found in the R language definition manual the passage that > discourages users of assigning objects within function calls since it > is not guaranteed that the assignment is ever made because of R's lazy > evaluation model. But this does not seem to explain the above > behaviour since the argument to print is evaluated. If I replace > sys.on.exit() with, say, ls() in both functions, then they produce the > same output (and the output that I expect). Why does f2() not work > with sys.on.exit()?It does work, but you seems to have misunderstood what it does. See e.g. the `bug' report discussed at http://tolstoy.newcastle.edu.au/~rking/R/devel/05/02/2112.html You might find g <- function(test) {} f2 <- function(){ par.def <- par(no.readonly=TRUE) on.exit(par(par.def)) g(tt <- sys.on.exit()) str(tt) invisible() } f2() illuminating. -- Brian D. Ripley, ripley at stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UK Fax: +44 1865 272595
Martin Maechler
2005-Dec-02 13:44 UTC
[Rd] all.equal() for mismatching names {was "Enlightenment sought..."}
>>>>> "BeT" == Berwin A Turlach <berwin at maths.uwa.edu.au> >>>>> on Fri, 2 Dec 2005 18:31:13 +0800 writes:BeT> First, I recently had reasons to read the help page of as.vector() and BeT> noticed in the example section the following example: BeT> x <- c(a = 1, b = 2) BeT> is.vector(x) BeT> as.vector(x) BeT> all.equal(x, as.vector(x)) ## FALSE actually 'FALSE' was never the case, but "non-TRUE" once was, see below. BeT> However, in all versions of R in which I executed this example, the BeT> all.equal command returned TRUE which suggest that either the comment BeT> in the help file is wrong or the all.equal/as.vector combination does BeT> not work as intended in this case. For the former case, I attach BeT> below a patch which would fix vector.Rd. We recently had the following posting on R-devel https://stat.ethz.ch/pipermail/r-devel/2005-October/034962.html (Subject: [Rd] all.equal() improvements (PR#8191)) where Andrew Piskorsky proposed a (quite extensive) patch to all.equal() in order to make sure that things like names must match for all.equal() to return TRUE. I did agree back then, and Brian partly disagreed with the very valid argument that all.equal() has been used in code testing (particularly R CMD check for packges), and that changes to make all.equal() more "picky" might well have bad consequences for package testing. Also Andy didn't provide the necessary patches to the documentation that would have been entailed. Well, all that's just an excuse for the fact that I had really lost the topic out of sight ;-) However, I'd like to take up the case, and I believe we should fix all.equal() for at at least the following reasons: 1- logical consistency 2- earlier R versions were more picky about name mismatch (upto R version 1.6.2) : > x <- c(a=1, b=pi); all.equal(x, as.vector(x)) [1] "names for target but not for current" [2] "TRUE" 3- two versions of S-plus were more picky too, in particular, S+3.4 which used to be our prototype: > x <- c(a=1, b=pi); all.equal(x, as.vector(x)) [1] "names for target but not for current" attr(, "continue"): [1] T Here's Splus 6.2 : > x <- c(a=1, b=pi); all.equal(x, as.vector(x)) [1] "target, current classes differ: named : numeric" [2] "class of target is \"named\", class of current is \"numeric\" (coercing target to class of current)" ---- I really don't expect package checkings to fail because of a change. If some would start failing, a fix should be quiet simple for the package author and would help find inconsistencies in their own code IMO. Martin Maechler, ETH Zurich