[swift-evolution] [Concurrency] Async/Await

Joe Groff jgroff at apple.com
Wed Aug 23 11:44:50 CDT 2017

> On Aug 23, 2017, at 12:06 AM, Martin Waitz <tali at admingilde.org> wrote:
> Hello,
>> Am 22.08.2017 um 18:32 schrieb Joe Groff via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>>:
>> The feature provides general delimited continuations. You could write an IteratorProtocol-conforming interface over a coroutine like this:
>>  private func yield(_ value: T) async -> Void {
>>    self.next = value
>>    await suspendAsync { cont in
>>      resume = cont
>>    }
>>  }
>> This isn't ideal in a number of ways (awkward, not particularly efficient, and has the gotcha that the generator's `body` could suspend itself with something other than the `yield` operation, doesn't integrate with ownership in the way John proposes in the ownership manifesto), so it may not be a good idea, of course.
> I still have trouble understanding how exactly suspendAsync is going to work.
> Is the body called right away or is it put into some dispatch queue on another thread?
> Does the continuation function return immediately (besides queueing suspendAsync to also return)?

suspendAsync suspends the coroutine's context and passes it as a continuation into the body, which is executed immediately on the current thread. 

> How does this correlate with coroutines?
> There is no extra stack for the coroutine (which runs the generator function), right?
> In my mental model, the generator function is split into individual functions which are queued one after another, but reusing the same thread/stack, is this correct?

That's the way C# implements it, yeah, and it could be how we implement it as well. It would likely be the quickest way to get the feature up and running on existing platforms. I intentionally left the mechanism vague because there may be other implementation models we can explore within this model, such as running coroutines on their own lightweight growable stacks the way some other languages like Julia and recent versions of Go implement coroutines.

> How would a generator feature without the mentioned shortcomings look like?

The main thing missing from this model that generators need is a way to require a value to be yielded to the controlling context at each point the coroutine suspends itself. The proposal as written puts the responsibility for scheduling the continuation and passing data from async to sync into the caller of suspendAsync; this is good for async tasks since you don't generally want or need to expose dependencies on specific coordination mechanisms through an async task. One could complicate the model by making 'async' a typed effect, analogous to the frequently-requested "typed throws" feature, where the type of "async" is the type of value that is yielded back to the sync context at every suspension point.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170823/804d4309/attachment.html>

More information about the swift-evolution mailing list