[Python-Dev] PEP 340 -- concept clarification

Jim Jewett jimjjewett at gmail.com
Wed May 4 00:56:50 CEST 2005


Summary:  

Resource Managers are a good idea.
First Class Suites may be a good idea.

Block Iterators try to split the difference.  They're not as powerful
as First Class Suites, and not as straightforward as Resource 
Managers.  This particular middle ground didn't work out so well.

On 5/3/05, Guido van Rossum <gvanrossum at gmail.com> wrote:
> [Jim Jewett]
...
> > With the block, every yield returns to a single designated callback.
> > This callback had to be established at the same time the block was
> > created, and must be textually inside it.  (An indented suite to the
> > "block XXX:" line.)
 
> Doesn't convince me. The common use for a regular generator is in a
> for-loop, where every yield also returns to a single designated place
> (calling it callback is really deceptive!).

I do not consider the body of a for-loop a to be callback; the generator
has no knowledge of that body.

But with a Block Iterator, the generator (or rather, its unrolled version) 
does need to textually contain the to-be-included suite -- which is why 
that suite smells like a callback function that just doesn't happen to be 
named.
 
> And with a block, you're free to put the generator call ahead of the
> block so you can call next() on it manually:
> 
>     it = EXPR1
>     block it:
>         BLOCK1

> ... lets you call next() on it as you please (until the
> block is exited, for sure).

For a Resource Manager, the only thing this could do is effectively
discard the BLOCK1, because the yields would have been used
up (and the resource deallocated).  

I suppose this is another spelling of "resources are not loops".

> > But are there plenty of other use cases for PEP 340?
 
> Yes. Patterns like "do this little dance in a try/finally block" and
> "perform this tune when you catch an XYZ exception" are pretty common

...

Let me rephrase ...

The Block Iterator syntax gets awkward if it needs to yield more than
once (and the exits are not interchangable).  You have said that is OK 
because most Resource Managers only yield once.

But if you're willing to accept that, then why not just limit it to a Resource
Manager instead of an Iterator?  Resource Managers could look similar 
to the current proposal, but would be less ambitious.  They should have 
absolutely no connection to loops/iterators/generators.  There should be
no internal secret loop.  if they use the "yield" keyword, it should be 
described as "yielding control" rather than "yielding the next value."  There 
would be only one yielding of control per Resource Manager.

If limiting the concept to Resource Managers is not acceptable, then
I still don't think Block Iterators are the right answer -- though First Class
Suites might be.  (And so might "No Changes at all".)

Reasoning:

If there is only one yield, then you're really just wrapping the call to 
the (unnamed) suite.

(Q)    Why are decorators not appropriate? 

(A1)   In some cases, the wrapper needs to capture an 
instance-variable, which isn't available at definition-time.
(A2)   Decorators can be ugly.  This is often because the
need to return a complete replacement callable leads to too 
many nested functions.

These are both problems with decorators.  They do argue for
improving the decorator syntax, but not for throwing out the
concept.  I don't think that Block Iterators will really clear things 
up -- to me, they just look like a different variety of fog.

If decoration doesn't work, why not use a regular function
that takes a callback?  Pass the callback instead of defining an
anonymous suite.  Call the callback instead of writing the single
yield.

...

> ... you are proposing to solve all its use cases by defining an
> explicit function or method representing the body of the block. 

Yes.

> The latter solution leads to way too much ugly code -- all that
> function-definition boilerplate is worse than the try/finally 
> boilerplate we're trying to hide!

In the cases I've actually seen, the ugly function definition portions
are in the decorator, rather than the regular function.  It trades a
little ugliness that gets repeated all over the place for a lot of ugliness
that happens only once (in the decorator).

That said, I'm willing to believe that breaking out a method might 
sometimes be a bad idea.  In which case you probably want 
First Class (and decorable) Suites.

If First Class Suites are not acceptable in general, then let's figure
out where they are acceptable.  For me, Resource Manager is a good
use case, but Block Iterator is not.

-jJ


More information about the Python-Dev mailing list