Live data from Hacker News

Why numbering should start at zero (1982)

cs.utexas.edu

1–10 of 72 posts

Re: Why numbering should start at zero (1982)

#2
There's one important use case for Dijkstra's alternative (c), that is, an interval closed at both ends. That is when your set has a maximum element and you want to be able to express an interval including the maximum. This is, of course, important in any programming language whose basic integer types have a bounded range. For instance, the following loop in C never halts:

    for(uint8_t i = 0; i 
What's even worse, the following loop has undefined behavior because signed integer overflow is not defined:

    for(int8_t i = 0; i 

Re: Why numbering should start at zero (1982)

#3
post #2

There's one important use case for Dijkstra's alternative (c), that is, an interval closed at both ends. That is when your set has a maximum element and you want to be able to express an interval including the maximum. This is, of course, important in any programming language whose basic integer types have a bounded range. For instance, the following loop in C never halts: for(uint8_t i = 0; i What's even worse, the…

These would be peculiarities of the C programming language, not issues of typed integers or of expression ranges. Other, actually-strictly-typed languages will complain that 256 doesn't fit in a byte, or if 256 is a larger sized integer, that automatic comparisons between differently sized integer types is not allowed.

Re: Why numbering should start at zero (1982)

#5
post #2

There's one important use case for Dijkstra's alternative (c), that is, an interval closed at both ends. That is when your set has a maximum element and you want to be able to express an interval including the maximum. This is, of course, important in any programming language whose basic integer types have a bounded range. For instance, the following loop in C never halts: for(uint8_t i = 0; i What's even worse, the…

This is arguably a limitation of C-style for loops.

For example, Python:

   for i in range(0, 256):
Rust:

   for i in 0..256 {
and many other languages have similar things.

Proper ranges also mean that the compiler never needs to do complicated reasoning that may depend on signed integer overflow having undefined behavior in order to prove that the loop has a finite number of iterations or that `i` doesn't wrap around.

Re: Why numbering should start at zero (1982)

#7
Starting at 1 is more intuitive, and therefore IMO better.

Regarding some of the advantages of zero-based:

  - Indexing backwards from the "end". Your language can always add an `end` keyword like Matlab does, and this stops
 being an advantage.
  - Indexing cyclically using modular arithmetic. Yes, this is an advantage. Albeit a rare one for me.
I commit less off-by-one errors with 1-based, and I don't have to double-check as much -- so on balance, I prefer it.

[edit]

The amount of karma this comment is getting is undergoing something like Brownian motion.

Re: Why numbering should start at zero (1982)

#8
post #7

Starting at 1 is more intuitive, and therefore IMO better. Regarding some of the advantages of zero-based: - Indexing backwards from the "end". Your language can always add an `end` keyword like Matlab does, and this stops being an advantage. - Indexing cyclically using modular arithmetic. Yes, this is an advantage. Albeit a rare one for me. I commit less off-by-one errors with 1-based, and I don't have to double-che…

Heretic.

Re: Why numbering should start at zero (1982)

#9
post #7

Starting at 1 is more intuitive, and therefore IMO better. Regarding some of the advantages of zero-based: - Indexing backwards from the "end". Your language can always add an `end` keyword like Matlab does, and this stops being an advantage. - Indexing cyclically using modular arithmetic. Yes, this is an advantage. Albeit a rare one for me. I commit less off-by-one errors with 1-based, and I don't have to double-che…

Matlab uses 1-based indexing. I've used it extensively and it was definitely a bad move. One particularly annoying example is splitting an array into blocks, e.g.

  for i = 1:numel(s)
    foo(s[i])
  end
That is fine, but what if you want to process in blocks of N? Now you have to do:

  for i = 1:(numel(s)/10)
    foo(s[(i-1)*N + (1:N)])
  end
Ugh no thanks. This is as simple as it gets too. For more complex array manipulation... enjoy adding and subtracting your 1's. 0-based indexing is just way more natural.

Re: Why numbering should start at zero (1982)

#10
post #5
post #2

There's one important use case for Dijkstra's alternative (c), that is, an interval closed at both ends. That is when your set has a maximum element and you want to be able to express an interval including the maximum. This is, of course, important in any programming language whose basic integer types have a bounded range. For instance, the following loop in C never halts: for(uint8_t i = 0; i What's even worse, the…

This is arguably a limitation of C-style for loops. For example, Python: for i in range(0, 256): Rust: for i in 0..256 { and many other languages have similar things. Proper ranges also mean that the compiler never needs to do complicated reasoning that may depend on signed integer overflow having undefined behavior in order to prove that the loop has a finite number of iterations or that `i` doesn't wrap around.

Yes, I considered mentioning Rust as a more modern example. But even in Rust, ranges such as `0..max+1` are awkward enough that a closed range syntax was added to the language. With a range like `0u8..=255u8` you can also ensure that your induction variable can directly be passed to things expecting a u8 without a cast that might hide an accidental overflow.
Post reply on HN