[Python-ideas] Loop manager syntax

Andrew Barnert abarnert at yahoo.com
Tue Jul 28 19:48:55 CEST 2015

On Jul 28, 2015, at 19:17, Ryan Gonzalez <rymg19 at gmail.com> wrote:
> I feel like you're overcomplicating the internals if this.

Only because the internals _have_ to be overcomplicated if this is going to work. Unless you can come up with something simpler that actually works. Your solution doesn't solve any of the problems, so being simpler doesn't really matter.

> My personal implementation idea: functions.
> Basically, the pool example would be equivalent to:
> temp = Pool()
> def func(x):
> do_something
> temp.__for__(range(20), func)
> so that __for__ could be implemented like:
> def __for__(self, iter, func):
> # Do something with the pool

But now func has a different scope from the caller, so all of its assignments don't work.

Also, it's illegal to put break or continue statements directly inside a function. So the inner function still has to be compiled in some special way. But what should outer break and continue get compiled to? It can't be the jump opcodes they normally become. And whatever you do, surely the break and continue have to be communicated to the controlling function, or it's not controlling the loop. Hence the LoopBreak and LoopContinue exceptions from my version. How can you simplify those away? (And this still doesn't answer the question of what break is supposed to do to a parallel loop.)

And, while you say "yields and returns could be implicitly propagated", I'm not sure what that actually means semantically. For returns, how does the caller or the interpreter loop or anyone else even know whether the inner function did an explicit return (which has to get implicitly propagated) vs. just falling off the end (which can't be)? That's why I included the LoopReturn exception; I don't see how you can do without that either. If you want to make it more implicit, you can just make it so that if the controlling function doesn't handle LoopReturn, it's swallowed and the value of the LoopReturn is used as the value of the controlling function (not too different from StopIteration today), but that's adding more complexity onto my solution, not removing it.

And yield and yield from have the same problems as return, plus the much more serious question of what it means to implicitly propagate them, and to implicitly propagate the next or send that continues the generator. Also the question of how the __for__ method gets the generator flag set at runtime depending on whether the function it's going to call has that flag set--or, if not that, how it can yield (implicitly or otherwise) without being a generator.

And so on. Go through each of the problems I raised; your solution doesn't solve any of them, doesn't make any of them easier to solve, and makes some of them harder to solve.

As I mentioned, this might be easier if you were trying to control comprehensions instead of for statements, but it also seems less useful there because it really adds nothing you can't do with an explicit function call like pool.map.

More information about the Python-ideas mailing list