After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 688437 - Genie's "for" statement is very problematic
Genie's "for" statement is very problematic
Status: RESOLVED NOTABUG
Product: vala
Classification: Core
Component: Genie
0.18.x
Other All
: Normal normal
: ---
Assigned To: Jamie McCracken
Vala maintainers
Depends on:
Blocks:
 
 
Reported: 2012-11-16 04:44 UTC by Tal Liron
Modified: 2013-09-10 04:27 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Tal Liron 2012-11-16 04:44:57 UTC
Here are the two problems:

1) If the end is smaller than the beginning, then it loops from end to beginning
2) It cannot loop on empty ranges

Here's an example of the type of code most people would consider to work:

 var myarray = new array of string[size]
 ...

 for var i = 0 to myarray.length
   print myarray[i]

This would fail in subtle ways. If size is 0, then the loop would still execute once! (The range is 0 to 0, which includes 0.) Since there is no 0 element, you would get an assertion. Then there's something like this:

 var len = myarray.length - 1
 for var i = 0 to len
   print myarray[i]

This would run through the loop twice! For 0 and for -1.

Thus, in using the for loop to iterate array-like things, programmers have to be very careful:

 if myarray.length > 0
   for var i = 0 to myarray.length
     print myarray[i]
 
 if (len > 0) && (len > myarray.length)
  for var i = 0 to len
   print myarray[i]

I am sure many programmers other than me would fall into this trap!

One solution would be to use Python-style range statements, which exclude the range endpoint: range(1, 5) does *not* include 5. And range(myarray.length) does not include myarray.length (and returns an empty range if it is 0).

As it stands, I think Genie's default behavior is very error-prone.
Comment 1 Jamie McCracken 2013-09-08 23:47:13 UTC
Im not so sure about this -

Following code works:

for var x = 1 to 10
    print "test %d", x

for var x = 10 downto 1
    print "test %d", x

Also

var d = new array of string = {"test","this","array"}

for var i = 0 to (d.length -1)
    print d[i] 

works fine

marking as not a bug. If it still causes a problem please reopen with example where it fails
Comment 2 Tal Liron 2013-09-10 03:23:19 UTC
Jamie, I am worried that you did not look closely at my examples. They all show failures: you in particular picked examples that *do* work.

If you need another way to see it, please see my video demonstration:

http://www.youtube.com/watch?v=dFyD8--zs84

The issue with "if" begins in 32 minutes.
Comment 3 Jamie McCracken 2013-09-10 03:57:52 UTC
I watched it - why are you not using:

for var x in list
  blah

the for..in is the loop for things like lists, dicts etc. It always works faultlessly

the for x= 1 to 10 is for iterations a fixed number of times

If you believe the for loop is still broken then please attach sample code to this bug. Note I could not get the problems you got where you say it went from 0 to -1
Comment 4 Tal Liron 2013-09-10 04:27:30 UTC
I can confirm that the issue has been resolved in vala 0.21.1. The following doesn't explode anymore:

  var d = new array of string[0]
  for var i = 0 to (d.length - 1)
    print i.to_string() + " " + d[i] 

The above definitely failed in the past!

(As for why I don't use "for var x in list", sometimes that is not desirable if you also want an index var.)