Short-circuit Logic
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Thu May 30 12:40:52 EDT 2013
On Fri, 31 May 2013 01:56:09 +1000, Chris Angelico wrote:
> On Fri, May 31, 2013 at 1:02 AM, Ethan Furman <ethan at 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
More information about the Python-list
mailing list