On Sun, Jun 14, 2020 at 11:29 AM Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
On 14/06/20 12:05 pm, Chris Angelico wrote:
On Sun, Jun 14, 2020 at 9:54 AM Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
Likewise, it's legitimate to create an awaitable object and then await it later.
(Personally I think it *shouldn't* be legitimate to do that in the case of await, but Guido thinks otherwise, so it is the way it is.)
If it isn't, then how do you start multiple tasks in parallel?
There would need to be a primitive that takes an async def function and creates an awaitable from it. The API for spawning tasks would then take an async function and use this primitive to get things rolling. So it wouldn't be impossible to separate the two, but you would have to go out of your way to do it. It wouldn't be the usual way to do things.
(For more on this, look up the discussions about my "cofunctions" idea. It was very similar to async/await, except that the operations of calling an async function and awaiting the result were fused into a single syntactic entity.)
Hmm, I think I see what you mean. So awaiting it would be "spam(123)" and getting an awaitable for later would be "spam.defer(123)"? That would make reasonable sense. Still, I don't think it's of value, since part of the point of coroutines is knowing exactly where a context switch could happen. If you're fine with invisible context switches, you're probably better off with threads, because they're not vulnerable to unexpectedly blocking actions (a common culprit being name lookups before network transactions - you can connect sockets asynchronously, but gethostbyname will block the current thread). ChrisA