[Python-Dev] PEP 492: What is the real goal? (original) (raw)
Paul Sokolovsky pmiscml at gmail.com
Wed Apr 29 23:06:06 CEST 2015
- Previous message (by thread): [Python-Dev] PEP 492: What is the real goal?
- Next message (by thread): [Python-Dev] PEP 492: What is the real goal?
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Hello,
On Wed, 29 Apr 2015 20:19:40 +0100 Paul Moore <p.f.moore at gmail.com> wrote:
[]
Thanks for that. That does look pretty OK. One question, though - it uses an asyncio Queue. The original code would work just as well with a list, or more accurately, something that wasn't designed for async use. So the translation isn't completely equivalent. Also, can I run the produce/consume just by calling produce()? My impression is that with asyncio I need an event loop - which "traditional" coroutines don't need. Nevertheless, the details aren't so important, it was only a toy example anyway.
All this confusion stems from the fact that wikipedia article fails to clearly provide classification dichotomies for coroutines. I suggest reading Lua coroutine description as much better attempt at classification: http://www.lua.org/pil/9.1.html . It for example explicit at mentioning common pitfall: "Some people call asymmetric coroutine semi-coroutines (because they are not symmetrical, they are not really co). However, other people use the same term semi-coroutine to denote a restricted implementation of coroutines". Comparing that to wikipedia article, you'll notice that it uses "semicoroutine" in just one of a sense, and well, different people use "semi" part of a different classification axis.
So, trying to draw a table from Lua's text, there're following 2 axes:
Axis 1: Symmetric vs Asymmetric
Asymmetric coroutines use 2 control flow constructs, akin to subroutine call and return. (Names vary, return is usually called yield.)
Symmetric use only one. You can think of symmetric coroutines only call or only return, though more un-confusing term is "switch to".
Axis 2: "Lexical" vs "Dynamic"
Naming less standardized. Lua calls its coroutines "tru", while other
- "generators". Others call them "coroutines" vs "generators". But the real difference is intuitively akin of lexical vs dynamic scoping. "Lexical" coroutines require explicit marking of each (including recursive) call to a coroutine. "Dynamic" do not - you can call a normally looking function, and it suddenly pass control to somewhere else (another coroutine), about which fact you don't have a clue.
All four recombined types above are coroutines, albeit all with slightly different properties. Symmetric dynamic coroutines are the most powerful type - as powerful as an abyss. They are what is usually used to frighten the innocent. Wikipedia shows you example of them.
No sane real-world language uses symmetric coroutines - they're not useful without continuations, and sane real-world people don't want to manage continuations manually. Python, Lua, C# use asymmetric coroutines.
Python and C# use asymmetric "lexical" coroutines - the simplest, and thus safest type, but which has limitations wrt to doing mind-boggling things.
Lua has "dynamic" asymmetric coroutines - more powerful, and thus more dangerous type (you want to look with jaundiced eye at that guy's framework based on "dynamic" coroutines - you'd better rewrite it from scratch before you trust it).
-- Best regards, Paul mailto:pmiscml at gmail.com
- Previous message (by thread): [Python-Dev] PEP 492: What is the real goal?
- Next message (by thread): [Python-Dev] PEP 492: What is the real goal?
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]