Re:A viable solution for Python concurrency
by masklinn on Saturday October 16, 2021 @05:02AM
(#28886532)
> Python is my favorite language, and I can live with the explicit loop, but explicit scheduling is ridiculous. Just run the damn coroutine
You can't "just run the damn coroutine", that's not what coroutines are.
But that does point to the mistake of Python, at least from a UX perspective: coroutines are more efficient but they're also a lot more prone to use errors, especially in dynamically typed languages. Async functions should probably just have been tasks, which is what they are in JS.
Re:A viable solution for Python concurrency
by BiteCode_dev on Sunday October 17, 2021 @06:16AM
(#28895334)
I know, but we could make coroutine creates with async have a special marker that is different to yield and auto schedule.
Re:A viable solution for Python concurrency
by masklinn on Tuesday October 19, 2021 @06:25AM
(#28916631)
That’s what a task is.
Re:A viable solution for Python concurrency
by justusw on Friday October 15, 2021 @10:34PM
(#28885098)
I’m not an expert on Node.js but I was always under the impression that you couldn’t write await outside of an async function. Has that changed recently?
Re:A viable solution for Python concurrency
by BiteCode_dev on Saturday October 16, 2021 @04:50AM
(#28886477)
You can await at the top level of a module since node v14.8.
It has been proposed to Python: https://groups.google.com/g/python-ideas/c/PN1_j7Md4j0/m/0xy...
But I have no more info about it.
Re:A viable solution for Python concurrency
by shauns on Saturday October 16, 2021 @03:14AM
(#28886154)
You are right that you can only await in an async function, but you can call an async function anywhere and get back a Promise.
await-ing that promise is often what you want to do but there are other ways to do work once the promise has resolved.
- The event loop in JS is invisible and implicit. V8 proved it can be done without paying a cost for it, and in fact most real life python projects are using uvloop because it's faster than asyncio default loop. JS dev don't think of the loop at all, because it's always been there. They don't have to chose a loop, or thinking about its lifecycle or scheduling. The API doesn't show the loop at all.
- Asynchronous functions in JS are scheduled automatically. On python, calling a coroutine function does...nothing. You have to either await it, or pass it to something like asyncio.create_task(). The later is not only verbose, it's not intuitive.
- Async JS functions can be called from sync functions transparently. It just returns a Promise after all, and you can use good old callbacks. Instantiating a Python coroutine does... nothing as we said. You need to schedule it AND await it. If you don't, it may or may not be executed. Which is why asyncio.gather() and co are to be used in python. Most people don't know that, and even if you know, it's verbose, and you can forget. All that, again, because using the event loop must be explicit. That's one thing TaskGroup from trio will help with in the next Python versions...
- the early asyncio API sucked. The new one is ok, asyncio.run() and create_task() with implicit loop is a huge improvement. But you better use 3.7 at least. And you have to think about all the options for awaiting: https://stackoverflow.com/questions/42231161/asyncio-gather-...
- asyncio tutorials and docs are not great, people have no idea how to use it. Since it's more complex, it compounds.
E.G, if you use await:
With node v14.8+:
With python 3.7+: E.G, deep inside functions calls, but no await:With node:
With python 3.7+: Of course, you could use "run_until_complete()", but then you would be blocking. Which is just not possible in JS, there is one way to do it, and it's always non blocking and easy. Ironic, isn't it? Beside, which Python dev knows all this? I'm guessing most readers of this post will have heard of it for the first time.Python is my favorite language, and I can live with the explicit loop, but explicit scheduling is ridiculous. Just run the damn coroutine, I'm not instantiating it for the beauty of it. If I want a lazy construct, I can always make a factory.
Now, thanks to the trio nursery concept, we will get TaskGroup in the next release (also you can already use them with anyio):
Which, while still verbose, is way better:- no gather or wait. Schedule it, it will run or be cleaned up.
- no need to chose an awaiting strat, or learn about a 1000 things. This works for every cases. Wanna use it in a sync call ? Pass the tg reference in it.
- lifecycle is cleanly scoped, a real problem with a lot of async code (including in JS, where it doesn't have a clean solution)