[Python-Dev] PEP 340 keyword: Extended while syntax

Ron Adam 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():
         BLOCK

This will require a new keyword/operator 'from' to use in a 'from' 
expression:

    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:

or ...

     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.


Examples:

     while lock from locking(myLock):
         # Code here executes with myLock held.

     while f from opening("/etc/passwd"):
         for line in f:
             print line.rstrip()

     while retry from auto_retry(3, IOError):
         f = urllib.urlopen("http://python.org/peps/pep-0340.html")
         print f.read()

     while f from locking_opening(myLock, "/etc/passwd"):
         for line in f:
             print line.rstrip()

     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"):
         if err:
             print "IOError:", err
         else:
             f.write("guido::0:0::/:/bin/sh\n")


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 
as such.

     if VAR1 from GEN:
         print VAR1
     else:
         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):
         block

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.


Optimistically,
Ron_Adam




More information about the Python-Dev mailing list