On Fri, 31 May 2013 01:56:09 +1000, Chris Angelico wrote: > On Fri, May 31, 2013 at 1:02 AM, Ethan Furman <et...@stoneleaf.us> > wrote: >> On 05/30/2013 05:58 AM, Chris Angelico wrote: >>> If you iterate from 1000 to 173, you get nowhere. This is the expected >>> behaviour; this is what a C-style for loop would be written as, it's >>> what range() does, it's the normal thing. Going from a particular >>> starting point to a particular ending point that's earlier than the >>> start results in no iterations. The alternative would be an infinite >>> number of iterations, which is far far worse. >> >> If the bug is the extra three zeros (maybe it should have been two), >> then silently skipping the loop is the "far, far worse" scenario. With >> the infinite loop you at least know something went wrong, and you know >> it pretty darn quick (since you are testing, right? ;). > > You're assuming you can casually hit Ctrl-C to stop an infinite loop, > meaning that it's trivial. It's not. Not everything lets you do that; or > possibly halting the process will halt far more than you intended. What > if you're editing live code in something that's had uninterrupted uptime > for over a year?
Then more fool you for editing live code. By the way, this is Python. Editing live code is not easy, if it's possible at all. But even when possible, it's certainly not sensible. You don't insist on your car mechanic giving your car a grease and oil change while you're driving at 100kmh down the freeway, and you shouldn't insist that your developers modify your code while it runs. In any case, your arguing about such abstract, hypothetical ideas that, frankly, *anything at all* might be said about it. "What if Ctrl-C causes some great disaster?" can be answered with an equally hypothetical "What if Ctrl-C prevents some great disaster?" > Doing nothing is much safer than getting stuck in an > infinite loop. I disagree. And I agree. It all depends on the circumstances. But, given that we are talking about Python where infinite loops can be trivially broken out of, *in my experience* they are less-worse than silently doing nothing. I've occasionally written faulty code that enters an infinite loop. When that happens, it's normally pretty obvious: something which should complete in a millisecond is still running after ten minutes. That's a clear, obvious, *immediate* sign that I've screwed up, which leads to me fixing the problem. On the other hand, I've occasionally written faulty code that does nothing at all. The specific incident I am thinking of, I wrote a bunch of doctests which *weren't being run at all*. For nearly two weeks (not full time, but elapsed time) I was developing this code, before I started to get suspicious that *none* of the tests had failed, not even once. I mean, I'm not that good a programmer. Eventually I put in some deliberate errors, and they still didn't fail. In actuality, nearly every test was failing, my entire code base was rubbish, and I just didn't know it. So, in this specific case, I would have *much* preferred an obvious failure (such as an infinite loop) than code that silently does the wrong thing. We've drifted far from the original topic. There is a distinct difference between guarding against inaccuracies in floating point calculations: # Don't do this! total = 0.0 while total != 1.0: total += 0.1 and guarding against typos in source code: total = 90 # Oops, I meant 0 while total != 10: total += 1 The second case is avoidable by paying attention when you code. The first case is not easily avoidable, because it reflects a fundamental difficulty with floating point types. As a general rule, "defensive coding" does not extend to the idea of defending against mistakes in your code. The compiler, linter or unit tests are supposed to do that. Occasionally, I will code defensively when initialising tedious data sets: prefixes = ['y', 'z', 'a', 'f', 'p', 'n', 'ยต', 'm', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'] assert len(prefixes) == 16 but that's about as far as I go. -- Steven -- http://mail.python.org/mailman/listinfo/python-list