I like the idea of named breaks, but I *hate* the idea of numerically
labeled breaks, whether numbered from the inside or from the outside.

On the occasions—which are actually relatively frequent—that I want to
break all the way out of an inner loop, I wind up using a sentinel STOP
variable.  I know how to do that, but it's somewhat cumbersome with a few
lines of distracting code and a few pointless variables.  However, when I
think about it, it's not a number of LEVELS I want, but a particular
identified loop that I want to escape from.

And yes, writing a function can be an approach to this.  However, it's also
often cumbersome to reason through exactly every name that needs to be
captured as arguments, and often needs refactoring as the code is
developed.  Abusing a try/except structure is another approach.

The problem with numbers, beyond just being harder to count out, is that
they are fragile under refactoring.  Maybe I start with:

for thing in collection_1:
    for other in collection_2:
        if property(thing, other):
            break 2 # <- hypothetical numbered break

But then I realize I need:

for thing in collection_1:
    for other in collection_2:
        for  more in other.stuff:
            if property(thing, other):
                break 2 # <- hypothetical numbered break (oops, wrong now!)

With names this is just straightforward:

for thing in collection_1 NAMED things:
    for other in collection_2 NAMED others:
        for  more in other.stuff:
            if property(thing, other):
                break things # <- hypothetical named break

My capitalized keyword is deliberately not optimal since I'm not trying to
bikeshed syntax.  But it doesn't matter whether I add or remove the loop
over other.stuff for this to work.

Of course if I find myself nesting loops 7 levels deep, I desperately need
refactoring.  This feature could certainly be abused, like almost all
others.  But for 3-4 levels of loops, refactoring to functions is often
"heavier" than a 'break_things' sentinel Boolean variable.

I've gotten in the habit of using itertools.product() when it is possible.
But it isn't always possible... in fact, my example above is just a case
because the 3rd level loop loops over something dependent on the object of
the 2nd level loop.  And product() is never going to work with while loops,
which can also benefit from a nested break sometimes.

Overall, I'm definitely +1 on adding named breaks.  It depends on the
syntax somewhat, but the concept would be useful.  On the other hand, it's
come up numerous times over the years, and never quite happened.  And I've
written programs perfectly well without it.

-- 
The dead increasingly dominate and strangle both the living and the
not-yet born.  Vampiric capital and undead corporate persons abuse
the lives and control the thoughts of homo faber. Ideas, once born,
become abortifacients against new conceptions.
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/LDXY2YCHGD23ZEWFCU42PTYUJQIPN7CW/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to