Concrete Proposal: while ... and while ...

Paul Boddie paulb at infercor.no
Tue May 25 12:56:04 EDT 1999


Corran Webster wrote:
> 
> In article <927132579snz at vision25.demon.co.uk>,
> Phil Hunt <philh at vision25.demon.co.uk> wrote:
> >In article <7hsv80$g9j$1 at news.tamu.edu>
> >           cwebster at math.tamu.edu "Corran Webster" writes:
> >
> >If this is added to the language, it will make programs harder to read.
> >
> >With your notation the ``and while ...'' line goes at the same level of
> >indentation as the original ``while'' line; this makes it look as if it
> >is ending that block and starting another one.

A good point which I made several days ago.

> This is part of the point - it _is_ starting a new block.  I don't see
> it as making things any harder to read than "if .. elif ... else" or
> even the existing "while ... else ..." constructions.  I will agree
> with you that it could be more readable, but I think this is the best
> that can be done while not adding a new keyword.

I don't agree with this analysis, and I believe that I pointed out the pitfalls
with the suggested structure of this construct. By having two sections to the
loop, the "confinement" of the iteration isn't necessarily intuitive:

while:
  first_part
and while test1:
  last_part

At a casual glance two loops might be perceived, for example, and with long
loops spread over multiple pages (perhaps because lots of comments have been
included) this mistake might become more common. To consider this construct as
being similar to "if...elif...else" is a mistake - in that case the separate
blocks are *alternatives*.

Even when the above example is identified as being one entity, there is still
some initial confusion about the flow of execution. Obviously, once the meaning
of this has been learnt it should not be a problem to remember what goes on in
code like this, but stepping back and looking at this in a naive way might not
suggest to many people one single meaning. It might mean:

1. Loop in the first part until test1 is satisfied, then loop in
   the last part until test1 is no longer satisfied.

2. Start in the first part and then proceed to the last part if
   test1 is satisfied, then keep looping in the last part until
   test1 is no longer satisfied.

3. Start in the first part and then either:
   - proceed to the last part if test1 is satisfied, then return
     to the first part.
   - or exit the loop if test1 is not satisfied.

4. Consider each "while" block as an alternative. Perhaps in the
   above case we execute the first part endlessly unless test1
   is satisfied, in which case we confine ourselves to executing
   the last part repeatedly until test1 is no longer satisfied.

Some of these are stranger than others, but surely alarm bells should be ringing
given that it is fairly easy to find different meanings for what should be a
basic construct. Given the confusion over multiple tests in an extended form of
this construct, case 4 might not be so strange after all.

> >Perhaps it would be better to have the ``and while ...'' line indented
> >inside the while loop?
> 
> I think that would be very unnatural for python - it would make "and
> while" a statement in it's own right and open a whole new can of worms.
> What happens if it's used outside a while loop? What happens if there's
> two or more of them?  That would change this from a minor tweak to
> introducing a whole new construct into the language.  I doubt Guido would
> go for it, and I'd agree with him.

Agreed.

Whilst I don't lie awake at nights worrying about all the "while 1"s out there
up to no good, it would be nice to provide a better way of expressing loops with
the continuation/termination condition not being at the start. Since "do" is
considered off-limits, we could consider other keywords:

while:          # No getting away from this, sadly.
  first_part
break if test2  # Imaginative use of existing keywords.
                # No second block, however. It could confuse.

Yes, I'm not making any allowance for mid-loop tests, but then what is wrong
with the traditional approach? Notably:

while:
  first_part
  if test1:
    action      # Was second_part in original construct.
break if test2  # Or "not test1" in this case.

Of course, we could have done this:

while:
  first_part
  if test1:
    action
  else:
    break

But since that is the kind of thing being objected to in this discussion I won't
advocate this very much. ;-)

It is notable, however, that in what I presume was intended in the proposal
(case 3 above) the "and while" part behaves like an "if" but with an implicit
exit. In effect, all we seem to be saving is an "else: break", a "1" and a bit
of indentation.

Paul




More information about the Python-list mailing list