[Python-Dev] Re: anonymous blocks

Guido van Rossum gvanrossum at gmail.com
Wed Apr 27 06:47:14 CEST 2005

> > [Greg Ewing]
> >>* It seems to me that this same exception-handling mechanism
> >>would be just as useful in a regular for-loop, and that, once
> >>it becomes possible to put 'yield' in a try-statement, people
> >>are going to *expect* it to work in for-loops as well.

> > (You can already put a yield inside a try-except, just not inside a
> > try-finally.)

> Well, my point still stands. People are going to write
> try-finally around their yields and expect the natural
> thing to happen when their generator is used in a
> for-loop.

Well, the new finalization semantics should take care of that when
their generator is finalized -- its __next__() will be called with
some exception.  But as long you hang on to the generator, it will not
be finalized, which is distinctly different from the desired
with-statement semantics.

> > There would still be the difference that a for-loop invokes iter()
> > and a with-block doesn't.
>  >
>  > Also, for-loops that don't exhaust the iterator leave it
>  > available for later use.
> Hmmm. But are these big enough differences to justify
> having a whole new control structure? Whither TOOWTDI?

Indeed, but apart from declaring that henceforth the with-statement
(by whatever name) is the recommended looping construct and a
for-statement is just a backwards compatibility macro, I just don't
see how we can implement the necessary immediate cleanup semantics of
a with-statement.  In order to serve as a resource cleanup statement
it *must* have stronger cleanup guarantees than the for-statement can
give (if only for backwards compatibility reasons).

> >     """
> >     The statement:
> >
> >         for VAR in EXPR:
> >             BLOCK
> >
> >     does the same thing as:
> >
> >         with iter(EXPR) as VAR:        # Note the iter() call
> >             BLOCK
> >
> >     except that:
> >
> >     - you can leave out the "as VAR" part from the with-statement;
> >     - they work differently when an exception happens inside BLOCK;
> >     - break and continue don't always work the same way.
> >
> >     The only time you should write a with-statement is when the
> >     documentation for the function you are calling says you should.
> >     """
> Surely you jest. Any newbie reading this is going to think
> he hasn't a hope in hell of ever understanding what is going
> on here, and give up on Python in disgust.

And surely you exaggerate.  How about this then:

    The with-statement is similar to the for-loop.  Until you've
    learned about the differences in detail, the only time you should
    write a with-statement is when the documentation for the function
    you are calling says you should.

> >>I'm seriously worried by the
> >>possibility that a return statement could do something other
> >>than return from the function it's written in.
> > Let me explain the use cases that led me to throwing that in
> Yes, I can see that it's going to be necessary to treat
> return as an exception, and accept the possibility that
> it will be abused. I'd still much prefer people refrain
> from abusing it that way, though. Using "return" to spell
> "send value back to yield statement" would be extremely
> obfuscatory.

That depends on where you're coming from.  To Ruby users it will look
completely natural because that's what Ruby uses.  (In fact it'll be a
while before they appreciate the deep differences between yield in
Python and in Ruby.)

But I accept that in Python we might want to use a different keyword
to pass a value to the generator.  I think using 'continue' should
work; continue with a value has no precedent in Python, and continue
without a value happens to have exactly the right semantics anyway.

> > (BTW ReturnFlow etc. aren't great
> > names.  Suggestions?)
> I'd suggest just calling them Break, Continue and Return.

Too close to break, continue and return IMO.

> > One last thing: if we need a special name for iterators and
> > generators designed for use in a with-statement, how about calling
> > them with-iterators and with-generators.
> Except that if it's no longer a "with" statement, this
> doesn't make so much sense...

Then of course we'll call it after whatever the new statement is going
to be called.  If we end up calling it the foible-statement, they will
be foible-iterators and foible-generators.

Anyway, I think I'll need to start writing a PEP.  I'll ask the PEP
editor for a number.

--Guido van Rossum (home page: http://www.python.org/~guido/)

More information about the Python-Dev mailing list