[Python-Dev] PEP 340 keyword: Extended while syntax
rrr at ronadam.com
Thu May 5 18:27:20 CEST 2005
I expect there's an obvious reason why this hasn't been suggested
already that I'm not currently thinking of, but here it is anyway. :-)
How about an *extended while* syntax as a block keyword alternative?
Reasoning: The block statement resembles a "while" block in some ways in
that it is a conditional block that may be executed only once, or
possibly not at all (or many times). And the word "while" is also
descriptive of how a block is used.
while VAR1 from EXPR1():
This will require a new keyword/operator 'from' to use in a 'from'
VAR1 from EXPR1()
Where EXPR1 returns an anonymous iterator, and the expression (VAR1 from
EXPR1()) evaluates as True only if a value from the EXPR1 iterator is
received. Or possibly False if it is received and is None. [* see below]
The "for" tests for the name binding instead of testing the value of
VAR1, it may also be desirable to check VAR1 for None after it is recieved.
This would be translated as follows:
1 --> while VAR1 from EXPR1():
raise an error if EXPR1 is not an iterator.
2 --> while (VAR1 = _EXPR1_iter.__next__()): # internal
3 --> while True: # if VAR1 gets a new value
or 3 -> while False: # if VAR1 fails to get a value
[*]or 3 -> while False: # if VAR1 receives None
* Undecided on check for None. An iterator could always return
something, so testing for None would be needed; or it could refuse and
break the request somehow after it is called. In the later case None
could be a valid return value it may not desirable to finalize the
block. A while *might* be able to test for both.
while VAR1 from EXPR1() and VAR1!=None:
while VAR1 from EXPR1() and VAR1:
Order of placement could make a difference.
while VAR1 and VAR1 from EXPR1():
This would test the *last* VAR1 before getting a new value. That might
be useful in some situations. This may also be inconsistent with how
expressions are currently evaluated. I'm not sure if it's allowed for
names to rebound while evaluating an expression.
while lock from locking(myLock):
# Code here executes with myLock held.
while f from opening("/etc/passwd"):
for line in f:
while retry from auto_retry(3, IOError):
f = urllib.urlopen("http://python.org/peps/pep-0340.html")
while f from locking_opening(myLock, "/etc/passwd"):
for line in f:
while f from opening(filename, "w"):
while re_out from redirecting_stdout(f):
print "Hello world"
while f, err from opening_w_error("/etc/passwd", "a"):
print "IOError:", err
Because the *from expression* evaluates to a bool, it might be useful in
other places, although there may be reason to prevent it from being used
if VAR1 from GEN:
print "GEN didn't give me anything"
Another possibility is the use of xrange() in a block statements/ or
extended while statements.
while VAR1 from xrange(100):
This may blur the distinction between "for" loops and "while" loops,
although it may be a *good* thing since "for" can then always used
sequences, and the *extended while syntax* always use iterators. Which
to use, would be up to the programmer.
With that change xrange() support could be removed from "for" statements
in Python 3000, (I think Guido wants to do that.), and it then could be
used with "extended while" statements.
With this suggestion there will still only be two looping constructs,
"for" and "while", and I think the distinction between a normal "while"
and an extended "while" is made clear with the "from" keyword. I think
this would be much easier to understand, IMO, and also much easier to
read and teach as well. It uses already familiar syntax and adds a new
expression keyword instead of a new statement keyword.
A symbol might be possible instead of "from", so adding new keywords
could be avoided if "from" is out of the question.
More information about the Python-Dev