14 ms·
Why numbering should start at zero (1982)
- burnte 7y agoIt does, ask any shepherd, accountant, quartermaster, etc. It has a well defined meaning and use over the centuries which for hysterical reasons of economy it took on a second meaning equal to physical 1. Luckily it's the only case in computing where established meanings in base ten were changed to fit a base 2 world.
- akvadrako 7y ago1 and 0 have the same meaning in both bases
- burnte 7y agoCPU0 would disagree, for example. A non technical person might be forgiven for thinking a system that says CPU0 has no CPUs, when in fact it has one, again, for example. Many logical objects start their enumeration at zero and increment from there. There are four rings of operation in Intel CPUs, but they are labeled ring 0 through 3.
- akvadrako 7y agoI’m sorry but you don’t understand what number base means https://en.m.wikipedia.org/wiki/Radix https://en.m.wikipedia.org/wiki/Radix Nothing to do with starting number. And base 0/base 1 makes no sense.
- burnte 7y agoI'm sorry, but you clearly haven't heard of unary, or base 1, which is probably the earliest counting system which 1 is 1, 2 is 11, 3 is 111, etc. Tallymarks. You are correct base 0 would make no sense, however. But yes please explain to me the very thing we're talking about which is exactly what I was referencing when pointing out that using 0 as an identifier rather than a value is moderately counterintuitive.
- paulmd 7y ago"Should array indices start at 0 or 1? My compromise of 0.5 was rejected without, I thought, proper consideration." -- Stan Kelly-Bootle
- travisjungroth 7y agoI made a Python library that implemented this and gave a talk about it at PyCon: https://www.youtube.com/watch?v=yC9m2GInXqU&feature=youtu.be&t=330/ https://www.youtube.com/watch?v=yC9m2GInXqU&feature=youtu.be...
- andai 7y agoGave me a good laugh, thanks for this :) https://github.com/travisjungroth/Compromise https://github.com/travisjungroth/Compromise
- thijsvandien 7y agoIt's at 5:30.
- yesenadam 7y agoSo silly. I love it. The thing most worthy of the name "Python" I've seen, by a mile.
- BubRoss 7y agoIndices should start at 1, but in programming we mostly use offsets and call them indices which is one source of confusion that leads to this endless debate.
- gautamdivgi 7y agoA real problem and pretty sure quite a few bugs in mathematical toolsets happen because of this. It was a real pain translating formulae to code for numerical computing.
- mc3 7y agoRelevant xkcds: https://xkcd.com/394/ https://xkcd.com/394/ https://xkcd.com/1292/ https://xkcd.com/1292/
- HorizonXP 7y agoI totally agree with this. However, I'm trying to teach my 1 year old how to count. He's got 1, and 2 down, and we're working on 3 (He can say the numbers 1 to 10, I'm talking more about the concept of numbers). I would love to get him to understand 0 too, but I'm not sure how.
- teekert 7y agoHow many apples do you have when I give you 0?
- SlowRobotAhead 7y agoI’m an embedded C programmer who typically avoids dynamic allocation... so I know the answer is zero apples... but it doesn’t matter because I have to hold my hand out making a space for an apple to go just in case some day you do decide to hand it to me.
- yesenadam 7y ago>C programmer who typically avoids dynamic allocation Me too. But the problem is, maybe they'll give you a few. Probably not more than 10 or 20? Say 20 to be safe. So I'd keep an empty box ready.
- ilikehurdles 7y agoIf he's counting physical objects, perhaps add and remove objects until reaching 0 and explaining to him that this lack of objects is called 0?
- empath75 7y agoHe just will one day. It was my 2 year old's favorite number after a sesame street episode about it.
- teekert 7y agoYeah, it's pretty incredible, isn't it? Makes you realize that it's not just the training of the brain, that brain is growing and it is simply able to comprehend more as it grows, no training will do that. For some things, you just wait.
- tabtab 7y agoIn the business domain one is often counting and tracking explicit things: widgets, contracts, customers, complaints, pizzas, etc. When counting, you almost always start with 1. "1" fits the domain more naturally, and if you deviate, you'll likely spend code converting between the end-user's view and the code's view. The translation layer creates risk of errors and more code. Maybe weather forecasting or space probe orbit calculation is different, but 1 better fits biz. Dijkstra was not (primarily) a business domain coder. (Smarter languages, like Pascal, allow you to define the range, although I'm not sure if it has dynamic upper ranges.)
- tomjakubowski 7y agoI think you'd still start counting those things from 0, because it's a convenient and natural way to express that you don't have complaints, widgets or pizzas. Or, I suppose, you could start counting at 1, but use an optional type and use None for that case. But that makes doing arithmetic on those numbers ("widgets per pizza") harder than if you'd just used 0 to begin with.
- tabtab 7y agoI think you are mixing up indexing and default value setting. They are roughly related, but only roughly.
- marcosdumay 7y agoHum, no. He is using a generalized version of counting that works for 0 items too. A computer should start counting from 0, there's no reason to special case the empty set.
- mjevans 7y agoHumans should too for the same reason. Lets consider a measuring tool for fluids which is based on volume. What is a useful range for the index on the side that measures the currently non-air capacity? Many such devices, E.G. a measuring cup I've got at home in the kitchen, use a series of tick marks within a bounded scale of accuracy range ] with marks on both the top (of course) and also the bottom (it looks nice). While 0 isn't expressly labeled on many scales, it is part of the inclusive range by implicit nature. Thus as you point out the case of 0 units, and 'empty set' are one and the same in this real world example.
- eigenspace 7y agoVery subjective and context specific argument. Some things are more naturally numbered from 1, others from zero. Fence posts versus fence spans. Pointer arithmetic is a great example of a situation well adapted to 0 based numbering, and was quite relevant to many programmers when this was written. However, far fewer programmers nowadays interact with raw pointers directly. Personally, I run into more cases where I’d rather have 1 based numbering than zero, but your mileage may vary. It’s valuable to have a language which can support both.
- asveikau 7y ago> However, far fewer programmers nowadays interact with raw pointers directly. It doesn't have to be literally a memory pointer to run into the same phenomenon. For example, offsets into a file. I can think of an example when I was doing work on a file format, and 0 based indexing certainly helped simplify some logic.
- eigenspace 7y agoCorrect, I was merely pointing out that the main motivator of Dijkstra’s argument is not nearly as relevant as it was when this was written. I have no idea what indexing style is more appropriate to the hypothetical ‘average’ programmer, but I find myself preferring mostly 1 to N the most, followed next by -N to N and finally 0 to N. As I said originally, your mileage may vary, but I think it’s important that we use languages where many different indexing styles can be supported ergonomically, and in a way that avoids silly errors due to using the wrong index style. Type systems and generic functions help a lot with this. I think of it a lot like say, signed versus unsigned integers. Multiple useful ways of looking at the same bitwise data. Type systems generally save us from nasty errors with the various types of integers. They can do it with arrays too.
- daveFNbuck 7y agoDo you have any examples where 1 to N is a more convenient numbering?
- protonfish 7y agoThe first time I read this, I was ready to be convinced and left disappointed. His entire argument is based on avoiding "the pernicious three dots." What's so pernicious about them? They are short, clear, unambiguous, easy to type. Why don't we just get our computer languages to understand what "2, 3, ..., 12" means? Is there any other argument to start counting at 0 other than not defining a range using the three dots? If not, maybe starting at 1 (like everyone does outside of computing) is the better option.
- crooked-v 7y ago> Why don't we just get our computer languages to understand what "2, 3, ..., 12" means? Some languages already do: for example, in Ruby you can use (-5..-1) to get [-5, -4, -3, -2, -1]. It's lazy evaluation, so you can even do stuff like: Infinity = 1.0/0.0 (1..Infinity).step(2).take(5) #=> [0, 2, 4, 6, 8]
- burlesona 7y agoJust FYI you can get infinity without evaluating an expression: it’s defined on Float, Float::INFINITY
- acqq 7y ago> Ruby And before, Perl: https://perldoc.perl.org/perlop.html#Range-Operators https://perldoc.perl.org/perlop.html#Range-Operators I like ranges in Perl.
- noisem4ker 7y agoSame as in Haskell. https://wiki.haskell.org/List_comprehension https://wiki.haskell.org/List_comprehension
- mark-r 7y agoI remember seeing a rather convincing argument that 1.0/0.0 should not be infinity, but zero.
- 7y ago
- shanxS 7y agoI (almost) always fall victim of one-off errors in competitive programming when working with counting numbers in range. Sticking to convention like 2 ≤ i < 13, as Dijkstra observed for Mesa programmers, sounds like a good idea.
- Animats 7y agoDepends on whether you're measuring or counting. The article mentions Mesa's interval syntax, which gave programmers all the possible options: [1..100] (0 .. 101) [1 .. 101) [1 .. 101) were all the same interval, 1 to 100 inclusive. Bad idea. Great way to get off-by-one errors. Another bad idea from that era - Wirth's insistence that you shouldn't be allowed compile-time arithmetic in Pascal. Like. const tabsize = 100; var tab: array [0..tabsize-1] of integer; { NOT ALLOWED } No, you had to have a separate named constant for "tabsize-1", and it couldn't be initialized as "tabsize-1", either.
- lordalch 7y agoIsn't that just how you get `const ONE = 1` cruft?
- Someone 7y ago”Bad idea. Great way to get off-by-one errors.” I would think that depends on whether that gets taught at schools early in life. Intervals that are closed at the low and open at the high end also are convenient when using zero-based indexing (you want an easy way to express 0,1,2,…,n-1, and if you’re used to the notation [0,n) is nicer than [0,n-1]) I would think overloading the meaning of the various parentheses makes parsing and generating clear error messages harder, though (but not as hard as when one would follow ISO 31-11 and allow such things a ]3,7] for an half-open interval excluding 3, but including 7) I think the desire to not overload parentheses with yet another meaning is why ‘Modern’ languages tend to use an infix operator for ranges, e.g. ‘1 to 5’ or ‘1...5’, with Swift having the half-open variant ‘1..<5’ (IMO ugly, but clear, so I guess one would get used to it).
- a1369209993 7y ago> you want an easy way to express 0,1,2,...,n-1 I'm partial to the viciously set-theoretic[0]: for i in 5: print i # 0;1;2;3;4 0: finite ordinals[1] are 0={},1={{}}={0},2={{},{{}}}={0,1},3={{},{{}},{{},{{}}}}={0,1,2},Sx=x∪{x}={0,...,x} 1: aka naturals or nonnegative/unsigned integers
- transfire 7y agoThe only reason to count from zero is for the sake of array processing -- given a pointer to an array, the first element will be at pointer plus zero. That's significant for low-level code as it avoids an extra add one operation. However for high-level programming, starting at one has advantages. For instance what index to use to represent insertion of an element at the beginning? Being able to use zero for this is cognitively easier.
- tabtab 7y agoThat convention seems confusing to me, especially one new to the convention. If you need an explicit "insert at the start" operation, then do something like "x.insertAtStart(y)" instead of "x[0] = y".
- Sharlin 7y agoInsertion at the beginning is insertion at zero in most zero-based systems too. Inserting at zero means that the new element will end up at index zero, and the other elements are shifted forward. In a one-based system, similarly, insertion at the beginning should be insertion at one, not zero; doing it any other way would just be a source of off-by-one bugs.
- oarabbus_ 7y agoThe worst is google sheets API, which uses Javascript-based 0-indexing for some functions, but Excel-based 1-indexing for other functions. Nightmare!
- jandrese 7y agoI always love when you get a database query back into your 0 indexed language and the data is 1 indexed because that's how the database does it.
- mjevans 7y agoIt's trying to replace/inter-operate with Excel, so it has to maintain backwards compatibility; bug for bug, including design bugs. I couldn't tell you offhand if the logic you speak of is distinct to Sheets or if it's Sheets maintaining the same interfaces other spreadsheet software defined for those macro names long ago.
- psychometry 7y agoThere's not much reason in a high-level language to start at 0. Humans reason about iteration in terms of the natural numbers.
- deleted 7y ago[deleted]
- wnoise 7y agoThat doesn't help: mathematicians have two definitions for "the natural numbers", one starting at zero, and one at one.
- psychometry 7y agoIt's very clear which definition I'm using. No need to be so pedantic.
- goatlover 7y agoThe languages designed for scientific computing, which make heavy use of math libraries, start at 1.
- magicalhippo 7y agoI'm usually a start-at-zero guy, except if I'm implementing matrix routines... going from the 1-based indexing from the math theorems to 0-based code is so tedious in order to ensure the translation is correct.
- linuxlizard 7y agoI'd like to have a keyboard with a 0 (zero) to the left of the 1 (one) digit.
- snicker7 7y agoIn scientific-oriented languages (R, MatLab, Julia, Fortran, &tc.), array indicies tend to start at 1. I think it is a culture thing. Software engineers prefer 0. Scientists prefer 1.
- metalliqaz 7y agoThe scientists can do what they want until they start using computers, then they should listen to the software engineers.
- Certhas 7y agoThis is silly. Different domains have different needs. If you think of arrays as pointer + offset calculation, and your only for loop has an explicit index increment in it, then starting at 0 is natural. If you are a systems programmer then a language targeting you should accommodate that. If you are anyone who doesn't want to care (too much) about how things are implemented, then it's a lot less error prone to mark the 1st element of an array a[1]. Having taught and written fairly complex scientific code in both 0 and 1 indexed languages, there really is no good reason to do anything else. for a in array[3:6] Should iterate over the third to sixth element of the array.
- metalliqaz 7y agoI dunno man, it's Dijkstra's essay. He has a pretty good reputation.
- deleted 7y ago[deleted]
- contravariant 7y agoNah everyone should just listen to the mathematicians and allow for arbitrary index sets. Seriously though you save yourself a lot of trouble if you don't worry that much about what range your indices have but rather what they represent. The fact that they're integers starting at 0 is just an implementation detail.
- 7y ago
- raymondh 7y agoPython follows convention the first convention, just as Dijkstra recommends. Mostly this worked-out well except for the case of descending sequences. With half-open intervals, that case proved to be cryptic and error-prone, so we added reversed() to flip the direction of iteration. That allowed people to easily bridge from the comfortable and common case of looping forwards. Instead of range(n-1, -1, -1) we can write reversed(range(n)).
- mikepurvis 7y agoI was intrigued to see how this worked out in practice for Python 3, where range returns an iterator rather than a list— like, would reversing the iteration require allocating the whole list in memory? $ python3 -c 'print(reversed(range(10)))' <range_iterator object at 0x7fdb53ae96f0> It turns out that reversed() only works on objects that expose the __len__ and __getitem__ methods: https://www.python.org/dev/peps/pep-0322/ https://www.python.org/dev/peps/pep-0322/ If you try to use reversed() with your own generator it will fail with "TypeError: argument to reversed() must be a sequence", until you wrap the generator invocation in an explicit list(). Very nice.
- jacobolus 7y agoWith the new proxy feature, we can emulate Python 3 ranges in Javascript: https://observablehq.com/@jrus/itertools#range https://observablehq.com/@jrus/itertools#range
- thedirt0115 7y agoSome background on Python's choice for 0-based indexing: http://python-history.blogspot.com/2013/10/why-python-uses-0-based-indexing.html http://python-history.blogspot.com/2013/10/why-python-uses-0... See Guido's comment on calendar :)
- tomkaos 7y agoWorst than starting at 0 or 1 is two give the option. In old Visual Basic the "Option Base" statement change the indice for a whole module. I had to debug code program with a mix use of code with indice starting at 0 and 1.
- tenebrisalietum 7y agoOn the assembly language level, you have compare instructions. These subtract, and throw away the result, but leave the flags. Many CPUs have a flag that is automatically raised if a value is 0. This means you don't have to execute a compare instruction to test if a value is 0, because the "Zero" flag will be set as soon as the 0 value is loaded. That means you can load a value, and directly go to a BEQ (which is really shorthand for "if zero flag = 0") and save a few cycles by avoiding the CMP instruction. So this is why numbering starts at zero. Testing if your list is empty, which is probably a common thing if you loop through each element, is slightly quicker.
- waynecochran 7y agoCase: indexing an array in ASM, C, C++, Swift,… Case: using an offset 0 <= i < N Case: indexing an array in Pascal, Ada, … Case: writing a math paper Case: talking with a non-programmer 1 <= i <= N
- 0-_-0 7y agoLots of people have a strong opinion on this: Ones that say that 0-based indexing is the only logical way of things, and ones that don't see what the fuss is about and prefer 1 because that's how we count objects. I suspect the people in the first category did some low level programming that needed to do arithmetic on indices. For example, let's say you want to take a string "abc" and repeat it until the length is 10, getting "abcabcabca". Assuming some Python-like language you would start with: a = "abc" b = [" "]*10 With 0-based indexing you would do: for i in range(0,10): b[i]=a[i%3] In a 1-based language that becomes: for i in range(1,11): b[i]=a[(i-1)%3+1] So you need to shift the index twice. This is because modulo arithmetic needs 0 to form a ring. As a result, in situations where the difference between 0 and 1 based indexing makes a difference it's ususally 0-based indexing that leads to simpler code.
- kragen 7y agoDijkstra makes, I think, a stronger argument, particularly given that in languages like C, (-2) % 3 == -2 rather than 1 as it should.
- 0-_-0 7y agoThat's likely there to make modulo power-of-two operations faster by turning them into a single AND operation. Otherwise it doesn't make sense to me.
- kragen 7y agoThat's not why, no. Why don't you implement signed integer division (with shifts, masks, and adds/subtracts) and see what you come out with?
- 0-_-0 7y agoAccording to wahern's quote above it was to "avoid incurring overhead in run-time code to check for special case", like the ability to accelerate mod power-of-two by convertig to AND.
- jessermeyer 7y ago0 is the first number. 1 is the first number 1 unit from 0.
- LanceH 7y agoOne is the first number. Until there is one of something there is no point to counting at all. Zero is a regression from one and only significant for the lack of that something which we started counting at 1.
- baddox 7y agoBut there absolutely is a point in setting out to count something when it turns out there is zero of that thing. If you don't know how many of something there is, but you know that this information is important, you will want to go out and count. If it's really important, then you will likely want to keep records of the count every time you perform it. This is, of course, very important in commerce.
- LanceH 7y agoOops, I was wrong. A count is a quantity. This is numbering being talked about. Guy finishes a marathon in first place, he would be the zeroth runner and one runner has finished. Most people would intuitively like those numbers to line up. Of course, when you build the natural numbers on a computer and use those as indices to arrays, it makes sense that the first index is zero. So the first (common usage) element would then naturally be called the zeroth element. This, of course, gives you the problem that array.size == x means that array.last_index == x - 1 and all the off by one errors that entails.
- mjevans 7y agoYour logic is missing a temporal element check. Before any runners have completed the race, there are 0 runners in the set of runners that have completed the race (empty set/null set). As soon as the first runner crosses the finish line 1 runner has finished the race, increasing the counter by one increment and it is customary to assign them the designation of the upper end of the unit range rather than the lower number. Thus, they are the First (1st) runner to have completed the race. We count rooms the same way probably out of a similar convention, the first room on a floor is numbered 1, rather than 0, because it is more useful to annotate the end of the range than the start. It makes a lot of math easier too. If there are 10 rooms on a floor and 10 guests, there are 0 rooms free.
- jedberg 7y agoAt the end of the day they are both great and they both suck depending on context. I use 0 based when programming and 1 based pretty much everywhere else. And in both cases I always run into an issue where I think, "This would be so much easier if we just started at [the other index]".
- mumblemumble 7y agoI use 0 based when programming in some languages, and 1 based in others. Everywhere else I use 1 based. When I'm programming in 1-based languages, I'm almost always happy with that choice, because they're almost always languages designed for solving problems in a domain that were standardized on 1-based counting before Charles Babbage was born. When I'm programming in 0-based languages, I'm sometimes very happy with that. Those times are when I'm working in C or C++ . When I'm using other languages, I don't care much maybe 1/3 of the time. And the majority of the time I still wish it were 1-based, because I'm using that language to solve problems in a domain that had standardized on 1-based counting before Charles Babbage was born.
- mjw1007 7y ago« Exclusion of the lower bound forces for a subsequence starting at the smallest natural number the lower bound as mentioned into the realm of the unnatural numbers » There's a parallel argument for being inclusive in the upper bound: it lets you specify a range which is the entire size of your integer type. I can see that that might seem like a poor trade for losing the ability to represent an empty range starting at zero, but it seems a shame he didn't mention that this is the tradeoff you're making.
- codeulike 7y agoGreat to see this at position 1 on Hacker News
- DonHopkins 7y agoIt deserves to be at position 0.
- goatlover 7y agoPosition 0 doesn't exist.
- DonHopkins 7y agoNo, you just need to subscribe to HN Gold to see it.
- deleted 7y ago[deleted]
- nabla9 7y agoWhile I agree with the conclusion, i think he could have expanded it even more. Not everyone has as developed aesthetic sense. Measuring, counting, combinatorics, indexing, arithmetic with ranges. 95% of cases it does not matter or make things more elegant or simple, but when it does it's always zero-indexing that is more elegant.
- akvadrako 7y agoNo it doesn’t. One indexed means it equals counting. First person = index 1.
- hi41 7y agoI need help with this. I intuitively count with starting at one. In a for loop, if we start with 0, then the terminating condition is i less than n. However, ifvit starts at 1, then the terminating condition is i less than or equal to n. What mental trick do you use to remember that?
- fctorial 7y agon is n steps ahead of 0,and thats what < checks for.
- cedricbonhomme 7y agoIn the case of lists/arrays, it's because we count the number of shift. It's what I always thought. I see analogies with Turing machine.
- fctorial 7y agoA recent study has found the number of '+1's and '-1's in a codebase is around 15 times higher if you use 1 based indexing.
- thedirt0115 7y agoI was just wondering which was more ergonomic! Do you have a link to the study?
- crazygringo 7y agoI'd love to see the citation? Also I wonder if it's highly dependent on whether the domain is largely algorithmic (e.g. video codecs) or business logic (e.g. supply chain). And how much is simply the language being "misused", e.g. writing "<= n - 1" rather than "< n".
- fctorial 7y agoIt was an app I wrote, probably in algorithmic category. But even in business code, I very rarely see off by one problems that would be easier to handle in 1 based indexing. > e.g. writing "<= n - 1" rather than "< n" Wouldn't such errors further increase the ratio?
- crazygringo 7y agoI'm sorry, the "recent study" was "an app I wrote"? Sorry, but unless I'm misunderstanding... that's not a study. And the whole point of a study is to back up assertions like "I very rarely see" so they aren't just opinion subject to all the normal human biases we all have. But if you ran such an analysis across public GitHub repositories per-language and wrote the results up in a blog post, I'm sure HN would love to see it. Definitely front-page material.
- fctorial 7y agoIt wasn't a serious comment. I thought it was obvious from the tone. > But if you ran such an analysis across public GitHub repositories per-language and wrote the results up in a blog post, I'm sure HN would love to see it. I'll see what I can do. I do have some repos in sight that could be used for it. But even then this won't be as straightforward as you say since different languages have different applications (eg cpp for games, julia for scientific computing). This would require writing the same code in both indexing patterns and then comparing them.
- ivanhoe 7y agoOne detail that I always liked about zero-based arrays is that it makes for loops look nicer, using `i < length` instead of `i <= length`.
- hghhbvv 7y agoPurely functional languages have no reason to 0-indexed arrays. Imperative languages that deal with for loops are more logically consistent with 0-indexed arrays. I think.
- mirekrusin 7y agoNice quote at the end... "In corporate religions as in others, the heretic must be cast out not because of the probability that he is wrong but because of the possibility that he is right." Antony Jay
- scythe 7y agoOne thing that’s nice about it is that you can use a positive difference as an array index directly. This is nice when you want to store a function of the “distance” between two things, e.g. potential[] = {-10, -5, -3, -2.2, ...}; ... potential[r1-r2]. It also works nicely with modular arithmetic as ‘0-_-0 mentions in their post. More generally this corresponds to the array being a function from the natural numbers to some other values, and this function can only start at zero if the arrays start at zero. But if you want a function that starts at 1, you can just set x[0] = invalid().
- dang 7y agoDiscussed in 2018: https://news.ycombinator.com/item?id=17765034 https://news.ycombinator.com/item?id=17765034 2016: https://news.ycombinator.com/item?id=13186225 https://news.ycombinator.com/item?id=13186225 2015: https://news.ycombinator.com/item?id=9761355 https://news.ycombinator.com/item?id=9761355 2009: https://news.ycombinator.com/item?id=777580 https://news.ycombinator.com/item?id=777580
- marknadal 7y agoNo: https://hackernoon.com/dijkstra-is-wrong-and-so-am-i-f36e2fbd5ae4 https://hackernoon.com/dijkstra-is-wrong-and-so-am-i-f36e2fb...
- pwdisswordfish2 7y agoSilly article. Most of its points are actually arguments against JavaScript's type system and semantics, not zero indexing per se. (Consider how would they apply if we used letters for indexing, where there's no longer a superficially appealing zero value to special-case: ‘We should use B-based indexing, because A is a falsey value in JavaScript! Also, now we can use A to denote missing elements!’.) Others are empty appeals to vaguely defined ‘mathematics’ that ultimately boil down to historical legacy. It is true that most matrix theorems are formulated with 1-based indices. But mathematical notation is full of unfortunate historical accidents (like defining π to be half the circumference of the unit circle), so one should be cautious when drawing inspiration from it. And for what it's worth, set theorists start ordinal numbers from zero, and each ordinal a half-open interval of numbers which precede it: https://en.m.wikipedia.org/wiki/Ordinal_number#Von_Neumann_definition_of_ordinals https://en.m.wikipedia.org/wiki/Ordinal_number#Von_Neumann_d...
- gjm11 7y agoThe syntax I always want but no language I know of supports: for 1 <= i <= 10: do stuff for 0 <= i < 10: do stuff for 1 <= i < j <= 10: do stuff (In the last case, the exact order in which the 45 iterations happen should maybe be left unspecified; at any rate, it would be bad style to depend on it.) Downward iteration: for 10 >= i >= 1: do stuff Obviously this doesn't cover every case of "arithmetic for loop" that would be useful: sometimes you want a stepsize that's neither 0 nor 1. I'd be quite happy with a language in which I had to do that using a more general iterate-over-an-arbitrary-sequence construction; I'm tempted by options like for 100 <= i <= 1000 where i%3==1: do stuff but it's probably too clever by half; either you only support the simple "specify the value of the variable mod something that doesn't change while iterating" case, in which case users will complain that some obvious generalizations fail to work, or you support arbitrary predicates, in which case you have to choose between making the "easy" cases efficient and the "hard" cases not (in which case users will be confused when what seem like small changes have drastic effects on the runtime of their code) and making all of them inefficient (in which case users will be confused by how slowly their code runs in some cases).
- arh68 7y agoYou may enjoy Common LISP's looping: it's a whole minilanguage where you can say stuff like (loop for i from 1 upto 10 ..) (loop for i from 1 below 11 ..) (loop for i from 10 downto 1 ..) (loop for i from 10 above 0 ..) (loop for i from 3.5 to 7.5 by 0.25 ..) It does much more than that, I should mention; it's a whole mini-language/DSL (like format).
- kazinator 7y agoPlus loop has unspecified behaviors leading to nonportable code that OP might enjoy.
- gjm11 7y agoNot only may but do; I like Common Lisp a lot, and while some people complain that LOOP isn't lispy enough I personally do like it. But it doesn't have the elegance of just specifying the inequalities you want your loop variables to satisfy :-).
- wruza 7y agoPlease note that “counting” there is really “indexing”, as in 1st, 2nd, etc. Apart from indexing in programming languages, some commenters in this thread seem to have an idea of counting (indexing) real things from zero, as if it solved the -1 problem easily. But that is a natural offset between a quantity and a position. We could in theory rename our ordinals one backwards like: zeroth, first, second, and so on. But that would shift the meaning temporarily, and 0th would become new 1st. With new counting in mind, for an empty set [] count is 0, for [x] count is one and an ordinal for x is “zeroth”, -1 again dammit. Between 0 and 10 there is 10 one-sized intervals touching 11 connecting/borderline points (integers). You cannot make this fact go away, no matter which language you choose.
- waffletower 7y agoIf the author had contemplated this sentence before writing this pained and narrow-minded treatise: "Why thinking should start before writing", engineers would be slightly more capable of interacting with and designing for other human beings. Numbering is highly domain specific -- the concept of zero is not always relevant. And sometimes the lay perspective has primacy over others. I remember the intense arguments engineers had regarding when the new millennium was to start. There weren't celebrations on New Year's 2001 that could compete with the scale of those for the year 2000.
- javajosh 7y agoCounting a physical process, so you have to allocate space. 0 is that allocation, and as you move along the number line, you update that space (using "add 1"). Note that you only update the space at discrete intervals, which has surprisingly deep implications. Having a kid I've been thinking a lot about counting, and what it really is. It seems totally wrapped up in repetition, and so I'm wondering if teaching counting as a function of, say, circular motion doesn't give a better intuition than the usual "count this clump of things" approach. (Counting clumps requires the person to simultaneously introduce an ordering and then implement a kind of internalized repetition as they point and count rhythmically. My kid seems to struggle with the ordering part, and no wonder: N objects have N! orderings.)