2

For loops are usually inclusice, exclusive, meaning that you start at the bottom, and stops when you reach, but don't to the top. In Python:

for i in range(0,a):
    print(i)

would print 0 through a-1. The same applies for Java:

for(int i = 0; i < a; i++){
    System.out.println(i);
}

would also print 0 through a-1, allthough the syntax is somewhat clearer.

So what if you want to print every number up to a, inclusive? Would you write

for(int i = 0; i <= a; i++){
    System.out.println(i);
}

or

for(int i = 0; i < a + 1; i++){
    System.out.println(i);
}

I guess the first makes the most sense, you're looping while i is less or equals to a, but the less than sign could easily be overlooked. The a + 1 isn't that easy to miss, in my opinion.

So my question is: Is there a better alternative of the two, and is there a convension for this thing?

EDIT:
I just want to point out that i'm talking about integers here.

7
  • should that be "i < a + 1" in the second code sample?
    – cdkMoose
    Sep 17, 2013 at 21:21
  • 2
    "Better" is probably not what you're looking for. There won't be a measurable performance difference. "Clearer" would be a better choice.
    – Bobson
    Sep 17, 2013 at 21:25
  • 1
    Well, I never said anything about better being faster, did I? Clearer would probably be a better word, though.
    – MartinHaTh
    Sep 17, 2013 at 21:34
  • 4
    a <= b is not necessary the same as a < b + 1 if we are not constrained to integers (and I'm ignoring operator overloading and overflow as well). You may want to clarify the data types. Example: 1.1 <= 1 is false, but 1.1 < 1 + 1 is true. Sep 17, 2013 at 22:34
  • 2
    I disagree with the [On hold] status of this question. It is not opinion-based, it is experience-based. And indeed provided answers express expertise rather than opinion.
    – mouviciel
    Sep 18, 2013 at 5:34

3 Answers 3

11

Say what you mean.

If you mean that the loop should run while the index variable is less than or equal to a, say that.

the less than sign could easily be overlooked

The <= operator is very common, particularly in loops. Trust your audience to be able to correctly read correctly written code. Don't avoid the natural solution simply because of a perceived possibility that some unknown future reader might need to get their eyes checked.

The a + 1 isn't that easy to miss

It's not that easy to understand, either. What would you think if you saw the code that you're proposing? I'm pretty sure I'd think something like:

Why are we talking about a + 1 when the loop obviously should run up to a? Oh, wait... I'm looking through the code, and this guy seems to have a phobia about <=... It doesn't appear anywhere in the code, and I see a few places where he goes out of his way to avoid it...

For loops are usually inclusice, exclusive

That assumption is incorrect. For loops continue while the looping condition is true.

The Python example you give is "inclusive, exclusive" only because Python's range(0,a) happens to generate the list 0..a-1. The whole "inclusive, exclusive" idea is a red herring -- it only applies because range() happens to work that way.

You could easily write your own range-like function that returned 0..a inclusive and use that to control your loop. Or you could supply your own list instead of relying on range() to generate the list:

list = [1, 2, 3]
for i in list
   ...

In this case the loop will execute three times, once for each value in list. In other words, it's not the for loop that's excluding a in your example, but rather range().

4
  • When saying that <= is easier to read, aren't you also implying that the i < a + 1 isn't really good for anything? I can't come up with an example where you would need to loop until, exclusive, i reaches a + 1
    – MartinHaTh
    Sep 17, 2013 at 22:03
  • @MartinHaTh I suppose you'd need it if i were a float and you wanted to allow values in the range [a..a+1), but I don't see the need simply to avoid <=. On the other hand, if one needs to write i < a + 1, that must mean that <= is sufficiently hard to read/understand that we should take pains to avoid it, and I don't believe that's true.
    – Caleb
    Sep 17, 2013 at 22:15
  • 1
    "the second parameter to range() isn't an upper bound, it's the number of values to generate". This is incorrect. The second parameter to range most definitely is an upper bound. Try range(5,10), for example. Sep 17, 2013 at 22:44
  • @JohnBartholomew Thanks for that -- you're right, of course, and I should have known that from the name. I'll correct that now.
    – Caleb
    Sep 17, 2013 at 23:17
23

The best convention is readability: Write code as close to your intent as possible.

If you mean: i should be less than or equal to a, then write i <= a.

If you mean: i should be less than a+1, then write i < a+1.

5
  • Could you come up with an example for each? I'm having a problem doing so. They are the same, after all.
    – MartinHaTh
    Sep 17, 2013 at 21:36
  • They are only the same in the case of ints. In the case of real numbers they are not the same and if in the future the increment changes to something like 0.5, one of these two expressions would be incorrect. So always write as close to what you mean as possible.
    – Stephen
    Sep 17, 2013 at 23:10
  • @MartinHaTh: Think of it this way, when enumerating an array is it easier to read i < length or i <= length - 1. The former is more readable because you know that the index has to be less than the length. Similarly if you have an inclusive end-point (as in your example) we typically think of it inclusively, making the <= notation more readable.
    – Guvante
    Sep 17, 2013 at 23:14
  • 1
    Both may be mathematically true, but one may be more correct at a casual level. If the problem specification says "The value must be no more than the threshold", i <= a best captures the concept, even though i < a+1 would also work. Sep 17, 2013 at 23:15
  • 1
    Language conventions are critical to readability. In C/C++/Java, a loop with <= is almost always wrong. In Pascal, a loop will usually have <= ....
    – mattnz
    Sep 18, 2013 at 3:24
5

Less than or equal is 1 assembler instruction.

a <= b

On the X86 family of processors the above would be something like:

MOV EAX, _a_
CMP EAX, _b_
JLE _label_

Less than or b plus 1 is two extra assembler instructions.

a < b+1

Whereas, the above would be something like:

MOV ECX, _a_
MOV EDX, _b_
ADD EDX, 1
CMP ECX, EDX
JL _label_

To argue that one method is more readable than another is simply silly. They are both equally readable, but <= should be the standard. Anyone doing b+1 is unnecessarily adding extra tasks for the language to perform. It doesn't matter if it's Java, C#, C++ or PHP because you're telling it to perform an unnecessary addition. If you're lucky the compiler you're using will optimize this out.

Someone answered:

If you mean: i should be less than or equal to a, then write i <= a.

If you mean: i should be less than a+1, then write i < a+1.

That makes no senses at all, because the two mean exactly the same thing. The correct answer is less than or equal. The easiest to read math expression is always the simplest i <= a.

9
  • i <= a and i < a + 1 only mean the same thing because the OP is talking about integers. Even in that case the latter obfuscates the intent, which is of course i <= a.
    – Caleb
    Sep 17, 2013 at 23:41
  • 3
    I'm guessing that if the data type is in fact an integer, almost every compiler/jitter would optimize this out. You'd have to incredibly unlucky for it to have any noticeable impact. Unless you're writing C code for an embedded RTOS, it's not worth worrying about micro-optimization like this.
    – Aaronaught
    Sep 18, 2013 at 1:09
  • 1
    -1 For the presumptuous premature optimisation and x86 assembler, neither were mentioned by the OP. Engineering time cost exceeded hardware cost for a vast majority of software about 30 years ago.
    – mattnz
    Sep 18, 2013 at 3:21
  • 4
    I disagree that they're equally readable. If I see a + 1 in an expression, I'm going to assume that there is something significant about the value a + 1. In this case, there isn't, and my assumption is incorrect. Expressing the loop as i < a + 1 is not commonplace behaviour and is distracting. It violates the principle of least astonishment. Sep 18, 2013 at 4:32
  • 1
    @MathewFoscarini - I certainly don't find i < a + 1 more readable. As I said, it is misleading and distracting. Sep 19, 2013 at 2:29

Not the answer you're looking for? Browse other questions tagged or ask your own question.