Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Thoughts on PEP315

Reply
Thread Tools

Thoughts on PEP315

 
 
Stephen Horne
Guest
Posts: n/a
 
      09-23-2003

PEP315 (Enhanced while loop) suggests a syntax as follows...

do:
...
while condition:
...

The motives are IMO good, but I don't like this solution. It
replicates a problem with the C do loop (even though this is actually
different to the C do loop).

Imagine that you can see the following in a piece of code...

statements1

while condition :

statements2

The question is this - is this a new old-style while loop starting at
this point, or is it the 'while' part of a new-style while loop? Given
the truncated view typical of a single screenful of code, this could
be far from clear. 'statements1' could follow after an earlier 'do:',
but it could equally follow after an earlier 'if ... :' or 'while ...
:' or whatever.

This is a situation where anyone who is unaware of the new 'do:' part
(or who simply didn't think about it) could end up being confused by
the 'while ... :' line.

This is not an unusual situation when the C 'do' loop is used, simply
because that loop is quite rarely used in practice - people don't
expect it, so when people see...

statements
}
while (condition);

the tendency is to assume that either the semicolon is a mistake, or
the while line is a conventional while loop with no body (not unusual
in C code if the condition has side-effects).

There are other issues. For example...

do :
...
while c1 :
...
while c2 :
...

Is the second 'while' line the start of a new loop, or is it a
continuation of the first loop (a second exit point)? If it is a
continuation, do you really potentially need to use a 'pass' to
prepare for a second loop...

do :
...
while c1 :
...

pass # to assert that the previous loop is ended

while c2 :
...

I basically think that this is too error-prone.

When faced with a problem inventing new language syntax, IMO the first
thing to do should always be to review other languages for existing
solutions. Why re-invent the wheel? Here, I'll limit myself to
alternate-to-while-loop structures which provide more flexibility than
a basic while loop (so I'm excluding Pascals repeat-until, for
instance, which is slightly different to but no more flexible than the
while loop).


First, ANSI Basic provides a generalised loop which is a bit more
flexible - it allows both a precondition and a postcondition.

do [while condition]
...
loop [until condition]

This can be useful in some situations, but it doesn't solve the PEP315
issue.

The C for loop deserves a quick mention because it isn't just an
integer for loop. The syntax is

for (<initialisation>; <precondition>; <'increment'>)
statement

Because the <initialisation> and <increment> can be any legal C
statements, the loop is quite flexible. Combined with the comma
operator, for instance, it allows 'in-step' loops such as this array
reverser...

for (i = <first item index>, j = <list item index>; i < j; i++, j--)
{
temp = array [i];
array [i] = array [j];
array [j] = temp;
}

Once again, though, this doesn't solve the PEP315 problem.

In terms of flexible loops, Ada is basically the Daddy. The mimimalist
for is...

loop
...
end loop;

But you can add a 'while' part or a 'for' part to the start...

while condition loop
...
end loop;

for i in 1..10 loop
...
end loop;

for i in reverse 1..10 loop
...
end loop;

And in addition, you can use an 'exit when' line (in any of the cases
above) to give essentially a conditional break...

loop
...
exit when condition;
...
end loop;

This last form finally handles the PEP315 problem. But Ada goes a
little further. Suppose you have nested loops, and you want to exit
more than just the innermost one? In Ada, you can name the loops and
specify by name which one you want to exit...

outerloopname: loop
innerloopname: loop
...
exit innerloopname when condition;
...
exit outerloopname when condition;
...
end loop;
end loop;

So what might be worth using in Python? I like the idea of an 'exit
when' line, which is basically what the PEP315 'while' line gives, but
I think a different syntax should be used. I would suggest that 'exit'
in the Ada loop means essentially what 'break' means in Python now,
except for the condition. So I would suggest the following as a
possibility...

while True :
...
break if <condition> :
...

This has no new keywords, but should be both clear and effective. The
parser should expect a semicolon immediately after existing break
keywords, so the distinction should be immediately clear to the Python
parser.

A 'continue if' might be considered as well.

That is sufficient to handle PEP315 with no new keywords and without
the 'is this a new loop?' confusion. Should the need for named loops
ever be considered in Python, there is also an obvious place to put
the name between the 'break' and 'if'.


What about all those other loop ideas, though...

1. Combining a precondition with a postcondition (ANSI Basic)...

No problem - just put the 'break if' at the end of the loop. It's
not an 'until' postcondition, but who cares. If anything, having
all loop conditions with the same 'sense' is more consistent.

while True :
...
break if <condition> :

statements after loop

2. In-step looping (C for loop)...

This is just syntactic sugar for a while loop anyway...

setup1
setup2

while condition :
statement

increment1
increment2

My personal opinion is that there is some need for a more
convenient iterate-over-integers, but this kind of stuff should
normally be done as above.

3. Named loops (Ada)...

Don't know. It may be a feature without a purpose. In the two
and a half years when Ada was my main language, I don't remember
ever using it.

4. Start-of-loop keyword which doesn't require a condition (Basic,
Ada)...

This is matched by the PEP315 'do', but is not actually necessary
if you use 'break if' for the exit point - you can simply use
'while True :' to start the loop without ambiguity.

But I admit it - the reason for going through the various languages is
because I'm sick of being accused of trying to change Python into *. I
don't think anyone can reasonably accuse me of trying to change Python
into Basic, C and Ada at the same time (maybe I should find a way to
get Prolog into the mix). Though it is slightly worrying that my
preferred idea was adapted from one particular language. Still,
traditionally I'm accused of trying to change Python into C, C++,
Java, Pascal, Haskell or more recently C# so at least Ada will (if I
remember right) make a change


--
Steve Horne

steve at ninereeds dot fsnet dot co dot uk
 
Reply With Quote
 
 
 
 
John Roth
Guest
Posts: n/a
 
      09-23-2003

"Stephen Horne" <$$$$$$$$$$$$$$$$$@$$$$$$$$$$$$$$$$$$$$.co.uk> wrote in
message news(E-Mail Removed)...
>
> PEP315 (Enhanced while loop) suggests a syntax as follows...
>
> do:
> ...
> while condition:
> ...


I've snipped the rest of your lengthy analysis because I think
the problem is much deeper, and is essentially insoluble given
the structure of Python.

The difficulty is that there is no clear and obvious way of
distinguishing subordinate groupings from the main grouping.

Consider the if statement:

if something:
blah blah
elif something_else:
blither
else:
bletch

If we look at this, without knowing the syntax of the
if statement, it looks like three primary statements.
There is no a priori way of knowing, from the lexical
structure of the language, that elif and else cannot
occur by themselves, but must be preceeded by
a specific statement. You need the additional layer
of the syntactic relationships.

Consider the same structure in Ruby:

if something
blah blah
elsif something_else
blither
else
bletch
end

The thing that makes all the difference is the "end"
statement which closes the if. The elsif and the else
are clauses within the if statement, and there is no
way of missing that fact even if you don't know the
exact syntax of the if structure.

If we now go back to the loop suggestion,
it becomes rather obvious what needs to be
done:

do:
bibbity
bobbity
boo
while condition # note the lack of a colon!

This is at least unambiguous as to what is
going on.

I don't, by the way, think that we need this
particular piece of syntactic sugar, regardless
of the syntax we dress it up in.

John Roth

>
>
> --
> Steve Horne
>
> steve at ninereeds dot fsnet dot co dot uk



 
Reply With Quote
 
 
 
 
Stephen Horne
Guest
Posts: n/a
 
      09-23-2003
On Mon, 22 Sep 2003 21:47:05 -0400, "John Roth"
<(E-Mail Removed)> wrote:

>
>"Stephen Horne" <$$$$$$$$$$$$$$$$$@$$$$$$$$$$$$$$$$$$$$.co.uk> wrote in
>message news(E-Mail Removed)...
>>
>> PEP315 (Enhanced while loop) suggests a syntax as follows...
>>
>> do:
>> ...
>> while condition:
>> ...

>
>I've snipped the rest of your lengthy analysis because I think
>the problem is much deeper, and is essentially insoluble given
>the structure of Python.
>
>The difficulty is that there is no clear and obvious way of
>distinguishing subordinate groupings from the main grouping.
>
>Consider the if statement:
>
>if something:
> blah blah
>elif something_else:
> blither
>else:
> bletch
>
>If we look at this, without knowing the syntax of the
>if statement, it looks like three primary statements.
>There is no a priori way of knowing, from the lexical
>structure of the language, that elif and else cannot
>occur by themselves, but must be preceeded by
>a specific statement. You need the additional layer
>of the syntactic relationships.


I disagree. You seem to saying that the *only* relevant aspect of the
lexical structure is the use of indentation and colons. I say the use
of distinctive keywords for continuation-of-same-block-structure such
as 'elif' or 'else' is easily sufficient clarification.

The PEP315 system of...

do:
...
while condition :
...

is IMO broken simply because there is no lexical indicator in that
'while' line that it is a continuation rather than a new structure. It
isn't a distinctive keyword because 'while' can obviously be the start
of a loop.

'break if <condition> :', however, is lexically clear at the point
where it is written - the 'break' on itself isn't distinctive, but the
'if' following straight after makes it unambiguous that this is a
continuation of an existing loop rather than a separate break
statement.

>Consider the same structure in Ruby:
>
>if something
> blah blah
>elsif something_else
> blither
>else
> bletch
>end
>
>The thing that makes all the difference is the "end"
>statement which closes the if. The elsif and the else
>are clauses within the if statement, and there is no
>way of missing that fact even if you don't know the
>exact syntax of the if structure.


If you don't know the syntax of such fundamental things as the basic
block structures in the language, you really shouldn't be reading or
writing code IMO. Especially when these are such common concepts among
languages that you should be able to understand it even if you've
never used Python, simply from experience of virtually any other
imperitive language.

>If we now go back to the loop suggestion,
>it becomes rather obvious what needs to be
>done:
>
>do:
> bibbity
> bobbity
> boo
> while condition # note the lack of a colon!


Yuck!!!

This is really no different to the following, which is quoted in the
PEP as something to move away from...

while True :
...
if condition : break
...

The fundamental problem is that the exit point is not obvious because
it is 'hidden' in the detail of the loop - it is a statement within
the loop body instead of being lexically a part of the loop.

Imagine if the if statement with an else clause were written...

if condition :
statement;
statement;
statement;
else;
statement;
statement;
statement;

That is basically the situation with break at the moment - it is a
feature of the loop, but it is not lexically related to the loop. It
is IMO useful in terms of readability to make the exit point lexically
a part of the loop - to write it at the same indent level and to add
on the colon.

This is somewhat novel - I can't think of a language that does that.
Ada does have 'exit when' but it treats it as if it were any other
statement in lexical terms. Of course Ada programmers are free to put
the 'exit when' at any indentation level they like, and the approach
of matching it to the indent level of the start-of-loop line is in my
experience far from unusual.

Anyway, the thing is that just because it is unconventional doesn't
mean that it's wrong. Treating 'break' and 'continue' as just another
statement is IMO a mistake.

There is an advantage - being able to break out of the loop from a
nested structure (such as an if) but if the break is conditional
anyway, that justification mostly disappears.

>This is at least unambiguous as to what is
>going on.


I don't think 'break if' would be unambiguous. I think it would be
less unambiguous than your suggestion, in fact, for two reasons...

1. Your suggestion is distinct from having an inner while loop *only*
because it lacks a colon at the end of the 'while' line. That,
IMO, is a recipe for confusion.

2. Your suggestion has the 'while' line as a standard statement, and
thus at the same indentation level as any other statement. When
reading code it would be very easy to miss this loop exit point.

>I don't, by the way, think that we need this
>particular piece of syntactic sugar, regardless
>of the syntax we dress it up in.


You may be right - but the PEP still exists, has been around since
April without being rejected, and claims to be scheduled for inclusion
in 2.4.

Syntactic sugar is basically what high level languages are about -
readability and maintainability being the key benefits (though you are
free to write machine code directly in hex - to avoid the syntactic
sugar called assembler - if you really want) - but the syntax
currently described strikes me more as syntactic vinegar. An alternate
syntax proposal seems to me more of a positive way forward. Though my
record in these matters is somewhat less that 100% (around 0% in fact)
so feel free to call me an idiot.


--
Steve Horne

steve at ninereeds dot fsnet dot co dot uk
 
Reply With Quote
 
Paul Foley
Guest
Posts: n/a
 
      09-23-2003
On Tue, 23 Sep 2003 01:47:03 +0100, Stephen Horne wrote:

> In terms of flexible loops, Ada is basically the Daddy.


http://www.lispworks.com/reference/H...ody/m_loop.htm

--
Let me control a planet's oxygen supply and I don't care who makes the
laws.

(setq reply-to
(concatenate 'string "Paul Foley " "<mycroft" '(#\@) "actrix.gen.nz>"))
 
Reply With Quote
 
Stephen Horne
Guest
Posts: n/a
 
      09-23-2003
On Tue, 23 Sep 2003 15:55:06 +1200, Paul Foley <(E-Mail Removed)>
wrote:

>On Tue, 23 Sep 2003 01:47:03 +0100, Stephen Horne wrote:
>
>> In terms of flexible loops, Ada is basically the Daddy.

>
>http://www.lispworks.com/reference/H...ody/m_loop.htm


Ah - OK - Ada is basically the wannabe Daddy that still lags a long
way behind Lisp in terms of flexibility. But it's still way ahead of
the imperitive languages I'm most familiar with.

Sorry about that.


--
Steve Horne

steve at ninereeds dot fsnet dot co dot uk
 
Reply With Quote
 
M-a-S
Guest
Posts: n/a
 
      09-23-2003
If it was up to me, I would propose

until <condition>:
<statements>

as an equivalent to:

<statements>
while not <condition>:
<statements>

and

loop:
<statements>

for the enless loop, instead of ugly 'while True'.

M-a-S

PS. And I'd introduce the switch construction of course.



 
Reply With Quote
 
Stephen Horne
Guest
Posts: n/a
 
      09-23-2003
On Tue, 23 Sep 2003 04:33:27 GMT, "M-a-S" <(E-Mail Removed)> wrote:

>If it was up to me, I would propose
>
>until <condition>:
> <statements>
>
>as an equivalent to:
>
><statements>
>while not <condition>:
> <statements>


If your reason for using 'until' is simply to test for 'while not',
then this doesn't make sense.

I assume you intend the 'until' to be a postcondition rather than a
precondition. Writing this at the start of the loop suggests that it
is a precondition (the word 'until' does not automatically imply a
postcondition). I want the condition to be written at the location
where it is tested - for a postcondition this means the end. Which
means you still need something to mark the start of the loop, and you
end up with...

loop:
<statements>
until <condition> :

Nothing wrong with that in particular of course, but it's not so
different to the 'break if' I proposed. No different at all, in fact,
except using a different name and...

>loop:
> <statements>
>
>for the enless loop, instead of ugly 'while True'.


I have no problem with that in principle, except that adding new
keywords can be a problem in itself. 'break if' avoids having a new
'until' keyword, and does not require a 'loop' keyword to replace the
'while'. Having a 'loop' keyword could be a good thing or not - it's a
different issue.

Of course, it might be acceptable to make the condition in the 'while'
optional, so you could write...

while :
<statements>
break if <condition> :


But then there would be the whole explicit-is-better-than-implicit
thing - I seriously doubt it would be accepted.

Alternatively...

for ever :
<statements>
break if <condition> :

The 'ever' wouldn't need to be a keyword - the lack of the 'in'
clearly differentiates it from existing 'for' loops so Python could
just validate the identifier name if it finds a colon where it expects
the 'in'.

You're suggestion of 'loop' certainly looks better than either of
these, but my suspicion is that looking good wouldn't outweigh the
need to avoid adding too many new keywords ("loop" may be used a lot
as an identifier name).


--
Steve Horne

steve at ninereeds dot fsnet dot co dot uk
 
Reply With Quote
 
Jordan Krushen
Guest
Posts: n/a
 
      09-23-2003
On Tue, 23 Sep 2003 06:08:06 +0100, Stephen Horne wrote:

> for ever :
> <statements>
> break if <condition> :


You could always hide something similar in a generator:


def forever():
while True: yield True

for now in forever():
print 'looping forever...'


....although I must admit, I don't really mind "while True:" that much.

syntactic-sugar-is-bittersweet-ly y'rs,

J.
 
Reply With Quote
 
Heather Coppersmith
Guest
Posts: n/a
 
      09-23-2003
On Tue, 23 Sep 2003 05:35:57 GMT,
Jordan Krushen <(E-Mail Removed)> wrote:

> On Tue, 23 Sep 2003 06:08:06 +0100, Stephen Horne wrote:
>> for ever :
>> <statements>
>> break if <condition> :


> You could always hide something similar in a generator:



> def forever():
> while True: yield True


> for now in forever():
> print 'looping forever...'



> ...although I must admit, I don't really mind "while True:" that
> much.


Don't forget that values other than "True" are true, too
(shamelessly stolen from a previous post from Tim Peters):

# basic file iteration (which can be done in other ways, but
# simply demonstrates my point)
while "there is another line in the file":
nextlinefromfile = getnextlinefromfile( )
if not nextlinefromfile:
break
moresprocessing( )

# typical server-like endless loop
while "[heck] has not frozenover":
command = getnextcommand( )
actoncommand( command )

strings-are-true'ly yours,
Heather

--
Heather Coppersmith
That's not right; that's not even wrong. -- Wolfgang Pauli
 
Reply With Quote
 
Tim Rowe
Guest
Posts: n/a
 
      09-23-2003
On Tue, 23 Sep 2003 04:39:14 +0100, Stephen Horne
<$$$$$$$$$$$$$$$$$@$$$$$$$$$$$$$$$$$$$$.co.uk> wrote:

>On Mon, 22 Sep 2003 21:47:05 -0400, "John Roth"
><(E-Mail Removed)> wrote:


>>do:
>> bibbity
>> bobbity
>> boo
>> while condition # note the lack of a colon!

>
>Yuck!!!
>
>This is really no different to the following, which is quoted in the
>PEP as something to move away from...
>
> while True :
> ...
> if condition : break
> ...
>
>The fundamental problem is that the exit point is not obvious because
>it is 'hidden' in the detail of the loop - it is a statement within
>the loop body instead of being lexically a part of the loop.


It is very different indeed. In the second case stuff can go after
the "if condition: break", so the terminating condition is potentially
buried in the surrounding code. On my reading of John's proposal
nothing can go after the "while condition", so the end is clearly
marked in the Python way by the indentation dropping back a level.

What I /don't/ like about it is the overloading of the "while"
keyword. I would much sooner reverse the condition and use "until",
though I realise the back-compatibility issues of introducing new
keywords.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
SOHO VPN design thoughts Timo.Green@gmail.com Cisco 4 09-22-2005 07:00 PM
Post your thoughts on the best hardware manufacturers ww_crimson Hardware 19 07-17-2005 02:40 AM
Thoughts on Catalyst 2948G-GE-TX? Dan Rice Cisco 0 06-23-2005 07:59 PM
Thoughts on WEP in WPA WLAN? Al Blake Cisco 3 05-17-2005 05:34 AM
Your thoughts on dual PIX 501 access - redundant SOHO access mh Cisco 6 05-10-2004 04:32 PM



Advertisments