From: "Guido van Rossum" <guido@python.org>
I think so far I've been thinking mostly about fitting my proposal on all edges (that's where my discussion of the thunk's scope comes from). Maybe I should try to focus more on collecting real-world examples that are asking for syntactic support, and then try to look for the simplest way to support most of them.
yes, real-world examples would be good.
[I leave aside generalizing 'class', which is something useful but not about control-flow statements and for me a separate problem]
Much of what:
do beh(args): (x,...): suite
can do, can be done already with
for x,.. in behgen(args): # behgen is a generator that yields where # beh would invoke the thunk suite
What is not covered is:
1) the case where the thunk passes back some result on invocation by beh using the proposed 'value' direct-to-caller-return statement. 2) the case where beh returns a useful value do e = beh(args): (x,...): suite
And 3) the case where the thunk is saved for later, e.g. when it is used as a callback or as some other extension of function definition. I haven't shown examples of this, but anonymous blocks in Smalltalk are used for this all the time. I can't find good docs about Ruby's iterators that describe whether this is possible or not.
I did find out that Ruby has two iterator syntaxes (do...end and {...}) that differ in whether they introduce a new scope or not!
Both could be adressed with the following similar syntax-sugar but that defines a usual function instead of a thunk:
fdo [e=] beh(args): [(x,...):] suite # can contain return
would be sugar for (or something similar):
def <anonymous>(x,...): suite [e = ] beh(args)(<anonymous>)
Yes, that's one of the cases that I had wanted to cover.
In this case we don't need to devise new rules for what 'break','continue','return' do in the suite. The suite is just the body of an anonymous function, 'return' has the usual meaning for a function in there. No new concept and rules would be added to the language.
Obviously the suite cannot rebind locals in the surrounding function. Given the functional flavor of the construct especially if there's an assigmnent e = or beh uses values produced by the suite, this can be considered a feature.
It just isn't a good way to implement things like synchronized(), which really need clean interaction with the environment (through break, continue, return, and local variable assignment). (I'm giving up on 'yield' for now.)
there would be 'with' ('using' in C#) for that.
The addition of 'with' and 'for' plus generators would cover the other cases!
Not case (3).
I was assuming that fdo (do) woud be also added, that would cover case 3, no non-local return and manipulation of surrounding locals, but e.g. for long-lived callbacks those would be warty.