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 | [EMAIL PROTECTED] | Brisbane, Australia --------------------------------------------------------------- http://boredomandlaziness.skystorm.net _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com