Hacker News new | past | comments | ask | show | jobs | submit login

True, but there are examples where 1-based indexing is easier, like returning the last element based on length. I think array[array.length] is easier to understand than array[array.length - 1].

Or the predecessor of the last element: array[array.length - 2] makes you think, whereas array[array.length - 1] is more obvious.




This is why Python has negative indices :) Then it's just my_list[-1] or my_list[-2].


But shouldn't it be [-0] to get the last element if [0] denotes the first element?


I think the most mathematically natural way to interpret negative indices is to threat them as numbers modulo list length. Then 0 = length, and -1 = length - 1.


C programmers can give you a couple of advises about "correct" modulo on negative numbers.


Negative indices have an implied ”len(list)” in front of them. They can be seen as an application of the idea of half-open intervals (0 <= i < len(list)), so it makes sense that they’re not symmetrical.


Is this sensible, or is it an unprincipled ad-hoc justification for a feature that happens to be useful?

Or another way: Is this more reasonable than, say, implicitly taking indices mod len(list)? How about implicitly flooring indices? If so, why?


I'm not sure on what principles you'd make a principled justification. My most common use of negative indices is for slicing the end of the list, in which context the interpretation similar to len(list) makes sense. E.g., list[:-2] does what you'd expect (the same as list[2:], except from the other end).

> implicitly taking indices mod len(list)?

Isn't this doing that (plus some bounds checking)? -1 mod 4 evaluates to 3.

> implicitly flooring indices?

Not sure I understand what this means.


[0] denotes an element with offset 0 from the start of the array. [-1] denotes an element with offset -1 from the start of the array.


Which Lua has also, for strings, and it's quite convenient.

Doesn't work for tables, though, because you can actually put something at foo[-1], which can be useful.

I find that foo[#foo+1] is more common than foo[#foo] in my code, that is to say I add to an array more often than I access the last slot. Although I typically use the idiomatic table.insert(foo, bar) instead— but that's mostly because it's slightly awkward to add the +1 all the time.


Icon (from the SNOBOL author) had the negative indices many years before Python and it is likely that this Python feature was inspired by it.


Negative indices are bug-prone. If you mess up iteration bounds, you should get an error, not silent incorrect indexing.


Can you give an example?


Sure. Let's take array elements in reverse, from m to m-n. Suppose n erroneously becomes larger than m. That should produce an error, not silently take several tailing elements.


sounds like a great way to introduce bugs


How so?


because when you misscalculate the index, then it will not crash, but use the wrong one

I'm getting this right?


I don't understand why that would be more error prone than using list[list.length-1]. It's just list[-1].


imagine if you used list[index] where index would be calculated

if you misscalculated something and went on negative, then you'd have big exception/error, but when negative indices are viable, then the code will work fine




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: