Given this from @Chris_Lattner3 over in another thread:
Also, [the use of
async let] doesn't align with other uses of
async in Swift which is very big deal as pointed out by many on this thread.
async means "this is suspendable" not "create a new task".
I want to ask one more time why we aren't considering reversing this by making
async let mean "asynchronous-interleaved-in-the-same-task" instead of "concurrent-in-a-new-task"?
As pointed out earlier in this thread, any desired concurrency in the RHS of an
async let initialization typically comes from concurrency of the underlying system function. For example, when retrieving network data, the desired concurrency will occur at the level of the network access, not at the level of the code that sets up the network access. Typically there is no real benefit to making the setup code concurrent in yet another task.
async let was actually asynchronous-but-not-in-a-new-task, that would also largely eliminate the discomfort about the RHS seeming to need braces to clarify that the execution context is different.
I guess I didn't properly understand before that no suitable execution mechanism had been proposed that would allow
async let to (for example) run its RHS interleaved with other code in the current task.
However, it occurs to me that there is an execution mechanism that does something just like that: the mailbox/queue for actor isolation.
If, for example, Swift's tasks could have a mailbox similar to an actor mailbox, then the
async let RHS could get interleaved behavior and could stay in-task, and so could avoid the semantic objections being voiced in this thread.
A side benefit (IMO) would be that
async let outside of actor scenarios would be safer. IIUC,
async let outside of an actor, as currently proposed, is thread-unsafe, because it permits cross-thread mutation of state.
That's a problem for all non-actor-related child tasks, of course, but it seems a bit more dangerous in
async let because the unsafety isn't very obvious.