[Rd] reference counting bug related to break and next in loops

William Dunlap wdunlap at tibco.com
Wed Jun 3 22:39:01 CEST 2009


help('while') says:
  Usage:
     for(var in seq) expr
     while(cond) expr
     repeat expr
     break
     next
  Value:
     'for', 'while' and 'repeat' return the value of the last
     expression evaluated (or 'NULL' if none was), invisibly. 'for'
     sets 'var' to the last used element of 'seq', or to 'NULL' if it
     was of length zero.

     'break' and 'next' have value 'NULL', although it would be strange
     to look for a return value.

Does the 'the last expression evaluated' mean (a) the value from
evaluating 'expr' the last time it was completely evaluated or
does it mean (b) the value of the last element of a {} expr that was
evaluated?  R currently follow interpretation (a), modulo reference
counting bugs.   My suggestion is to move to interpretation (b),
so that the fact that break and next return NULL would mean that
a broken-out-of loop would have value NULL.  (Personally, I'm happy
with S+'s return value for all loops being NULL in all cases, but
that might break existing R code.)

Of course, if the reference counting bug can be fixed without degrading
performance in ordinary situations (does anyone look at the return
value of a loop, particularly one that is broken out of?), then I'm
happy
retaining the current semantics.


Bill Dunlap
TIBCO Software Inc - Spotfire Division
wdunlap tibco.com  

> -----Original Message-----
> From: r-devel-bounces at r-project.org 
> [mailto:r-devel-bounces at r-project.org] On Behalf Of Wacek Kusnierczyk
> Sent: Wednesday, June 03, 2009 2:06 AM
> To: r-devel at r-project.org
> Subject: Re: [Rd] reference counting bug related to break and 
> next in loops
> 
> Wacek Kusnierczyk wrote:
> >
> > a simplified example may help to get a clear picture:
> >
> >     i = 1; y = 1:3;
> >     (while(TRUE) {
> >        y[i] = 0
> >        if (i == 2) break
> >        i = i + 1
> >        y })
> >     # 0 0 3
> >
> >     i = 1; y = 1:3;
> >     (while(TRUE) {
> >        y[i] = 0
> >        if (i == 2) break
> >        i = i + 1
> >        y + 0 })
> >     # 0 2 3
> >
> > the test on i is done after the assignment to y[i].  when the loop
> > breaks, y is 0 0 3, and one might expect this to be the 
> final result. 
> > it looks like the result is the value of y from the 
> previous iteration,
> > and it does not seem particularly intuitive to me.  (using 
> common sense,
> > i mean;  an informed expert on the copy-when-scared 
> semantics may have a
> > different opinion, but why should a casual user ever 
> suspect such magic.) 
> >
> > anyway, i'd rather expect NULL to be returned.  for the oracle,
> > ?'while', says:
> >
> > "'for', 'while' and 'repeat' return the value of the last expression
> > evaluated (or 'NULL' if none was), invisibly. [...]  'if' 
> returns the
> > value of the expression evaluated, or 'NULL' if none was. 
> [...]  'break'
> > and 'next' have value 'NULL', although it would be strange 
> to look for a
> > return value."
> >
> > when i is 2, i == 2 is TRUE.  hence, if (i == 2) break evaluates to
> > break.  break evaluates to NULL, breaks the loop, and the 
> return value
> > should be NULL.  while it is, following the docs, strange 
> to have q =
> > while(...) ... in the code, the result above is not 
> compliant with the
> > docs at all -- seems like a plain bug.  there is no reason 
> for while to
> > return the value of y, be it 0 0 3 or 0 2 3.
> >   
> 
> somewhat surprising to learn,
> 
>     i = 1
>     y = 1:3
>     (while (TRUE) {
>        y[i] = 0
>        if (i == 2) { 2*y; break }
>        i = i + 1
>        y })
>     # 0 0 3
> 
> where clearly the last expression evaluated (before the 
> break, that is)
> is 2*y -- or?
> 
> 
> vQ
> 
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
> 



More information about the R-devel mailing list