[Python-Dev] PEP 340 -- concept clarification
Nick Coghlan
ncoghlan at gmail.com
Wed May 4 13:33:25 CEST 2005
Phillip J. Eby wrote:
> This and other examples from the PEP still have a certain awkwardness of
> phrasing in their names. A lot of them seem to cry out for a "with"
> prefix, although maybe that's part of the heritage of PEP 310. But Lisp
> has functions like 'with-open-file', so I don't think that it's *all* a PEP
> 310 influence on the examples.
I've written up a few examples in the course of the discussion, and the more of
them I have written, the more the keywordless syntax has grown on me.
No meaningful name like 'with' or 'in' is appropriate for all possible block
iterators, which leaves only keyword-for-the-sake-of-a-keyword options like
'block' or 'suite'. With block statements viewed as user-defined blocks, leaving
the keyword out lets the block iterator be named whatever is appropriate to
making the block statement read well. If a leading 'with' is needed, just
include it in the name.
That is, instead of a 'block statement with the locking block iterator', you
write a 'locking statement'. Instead of a block statement with the opening block
iterator', you write an 'opening statement'.
The benefit didn't stand out for me until writing examples with real code around
the start of the block statement. Unlike existing statements, the keyword is
essentially irrelevant in understanding the implications of the statement - the
important thing is the block iterator being used. That is hard to see when the
keyword is the only thing dedented from the contained suite.
Consider some of the use cases from the PEP, but put inside function definitions
to make it harder to pick out the name of the block iterator:
def my_func():
block locking(the_lock):
do_some_operation_while_holding_the_lock()
Versus:
def my_func():
locking(the_lock):
do_some_operation_while_holding_the_lock()
And:
def my_func(filename):
block opening(filename) as f:
for line in f:
print f
Versus:
def my_func(filename):
opening(filename) as f:
for line in f:
print f
And a few more without the contrast:
def my_func():
do_transaction():
db.delete_everything()
def my_func():
auto_retry(3, IOError):
f = urllib.urlopen("http://python.org/peps/pep-0340.html")
print f.read()
def my_func():
opening(filename, "w") as f:
with_stdout(f):
print "Hello world"
When Guido last suggested this, the main concern seemed to be that the
documentation for every block iterator would need to explain the semantics of
block statements, since the block iterator name is the only name to be looked up
in the documentation. But they don't need to explain the general semantics, they
only need to explain _their_ semantics, and possibly provide a pointer to the
general block statement documentation. That is, explain _what_ the construct
does (which is generally straightforward), not _how_ it does it (which is
potentially confusing).
E.g.
def locking(the_lock):
"""Executes the following nested block while holding the supplied lock
Ensures the lock is acquired before entering the block and
released when the block is exited (including via exceptions
or return statements).
If None is supplied as the argument, no locking occurs.
"""
if the_lock is None:
yield
else:
the_lock.acquire()
try:
yield
finally:
the_lock.release()
Cheers,
Nick.
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net
More information about the Python-Dev
mailing list