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

Reply via email to