
Sven R. Kunze wrote:
# Call func syncronously, blocking until the calculation is done: x = func()
# Call func asyncronously, without blocking: y = await func()
Using the word "blocking" this way is potentially confusing. The calling task is *always* blocked until the operation completes. The difference lies in whether *other* tasks are blocked or not.
Whether this function achieves the goal by working asynchronously or blocking, AND if I, as a programmer, allow the function to work asynchronously, is a completely different matter. That in turn is extremely well reflected by the 'await' keyword (IMHO at least).
Another issue that bothers me, is code reuse. Independent from whether the 'async def' makes sense or not, it would not allow us to reuse asyncio functions as if they were normal functions and vice versa (if I understood that correctly).
You understand correctly. If the function is declared async, you must call it with await; if not, you must not. That's not ideal, but it's an unavoidable consequence of the way async/await are implemented.
So, we would have to implement things twice for the asyncio world and the classic world.
Not exactly; it's possible to create a wrapper that takes an async function and runs it to completion, allowing it to be called from sync code. I can't remember offhand, but there's likely something like this already in asyncio.
One last thing regarding 'async def', that came to my mind recently, is that it compares to that necessity of Java to decorate functions with all possible exceptions that could be raised inside.
It's a similar situation, but nowhere near as severe. There are only two possibilities, async or not. Once you've converted a function to async, you won't need to change it again on that score. -- Greg