I'm glad to see this moving forward. I have a few questions and comments.

First, I'd like it if someone could clarify for me what beginAsync and 
suspendAsync "actually do", and how they interact with `async` functions. I'm 
throwing a lot of good will at this but my brain is still fairly 
imperatively-wired, so let me try to rephrase this in more procedural terms and 
let's see if I got anything wrong.

My understanding is that an `async` function takes its continuation closure as 
a hidden parameter. That closure accepts as a parameter the "asynchronous 
return type" of the function. In other words:

    func foo() async -> Int

Can (give or take error handling and parameter names) be rewritten as:

    func foo(completion: (Int) -> Void) -> Void

This is fairly straightforward; it's just the inverse transformation of what's 
shown in the conversion section 
<https://gist.github.com/lattner/429b9070918248274f25b714dcfc7619#conversion-of-imported-objective-c-apis>.

The purpose of `beginAsync` is to start an `async` function while firewalling 
against the propagation of the `async` keyword to the caller. `beginAsync` does 
not return a value. By the time `beginAsync` returns, whatever continuation 
closure was generated for the `body` parameter has been passed off to someone 
else and some scheduling mechanism has a reference to it and will call it 
later. That's not giving me too much trouble either.

I'm somewhat bugged by `suspendAsync`. My understanding is that it allows you 
to take a synchronous function which accepts a callback and turn it into an 
asynchronous one, where "asynchronous" means "continuation-driven" more that 
"asynchronously executing", because something like `let foo: Int = await 
suspendAsync { $0(42) }` looks like it should be legal (although not 
particularly useful).

The interaction of `suspendAsync` and `await` is that `suspendAsync`, like any 
other `async` function, accepts a hidden closure parameter, and `await` takes 
the rest of the function and turns it into a continuation closure to pass as 
that hidden parameter. The explicit parameters of `suspendAsync` are closures 
that accept the continuation (either for success or failure), so `suspendAsync` 
is the primitive that's responsible for translating the rest of an `async` 
function into something that you can pass as a callback.

That seems to make sense to me (although I might have it wrong), but I'm having 
trouble with the terminology. I'm not trying to start a bike shed debate here; 
it's simply not immediately clear to me what "suspendAsync" means for a 
function that seems more about starting an "old world" asynchronous task than 
suspending anything (let alone an asynchronous thing).


Flurry of small questions:

* How does this interact with reference counting? The `suspendAsync` functions 
mark that its closures are @escaping,  yet `async` functions don't seem to need 
to write `self` to access members. What are the dangers?
* Are there ObjC functions right now whose continuation resembles 
`void(^)(Image* __nullable, Image* __nullable, NSError
* error))`, but for which only one of either the first or second Image 
parameter has a value if the call succeeded?
* in the DispatchQueue example, is there a meaningful difference between 
`syncCoroutine` and `asyncCoroutine`? Seems to me that `sync` is currently 
useful when you need your result before you return, but that doesn't really 
make sense to me in the context of an async function. Barring deadlocks in the 
synchronous version, the calling async function should return at the same time 
in both cases.
* Nit: the DispatchQueue example probably means `self.async`, and probably 
means `{ continuation() }` (and if not, someone needs to explain me what's 
going on).


The question where I just can't not get ahead of myself: you wrote that the 
underlying support can be used to implement generators. This is a feature that 
is very close to my heart. I understand that the compiler work that turns part 
of a function into a closure can be reused there; what about the higher-level 
stuff, do we foresee a set of more or less analogous keywords for generators, 
or should the async/await terminology be good enough to encompass any type of 
coroutine-based execution?


Thanks!

Félix

> Le 17 août 2017 à 15:25, Chris Lattner via swift-evolution 
> <swift-evolution@swift.org> a écrit :
> 
>> 
>> On Aug 17, 2017, at 3:24 PM, Chris Lattner <clatt...@nondot.org 
>> <mailto:clatt...@nondot.org>> wrote:
>> 
>> Hi all,
>> 
>> As Ted mentioned in his email, it is great to finally kick off discussions 
>> for what concurrency should look like in Swift.  This will surely be an epic 
>> multi-year journey, but it is more important to find the right design than 
>> to get there fast.
>> 
>> I’ve been advocating for a specific model involving async/await and actors 
>> for many years now.  Handwaving only goes so far, so some folks asked me to 
>> write them down to make the discussion more helpful and concrete.  While I 
>> hope these ideas help push the discussion on concurrency forward, this isn’t 
>> in any way meant to cut off other directions: in fact I hope it helps give 
>> proponents of other designs a model to follow: a discussion giving extensive 
>> rationale, combined with the long term story arc to show that the features 
>> fit together.
>> 
>> Anyway, here is the document, I hope it is useful, and I’d love to hear 
>> comments and suggestions for improvement:
>> https://gist.github.com/lattner/31ed37682ef1576b16bca1432ea9f782 
>> <https://gist.github.com/lattner/31ed37682ef1576b16bca1432ea9f782>
> 
> Oh, also, one relatively short term piece of this model is a proposal for 
> adding an async/await model to Swift (in the form of general coroutine 
> support).  Joe Groff and I wrote up a proposal for this, here:
> https://gist.github.com/lattner/429b9070918248274f25b714dcfc7619 
> <https://gist.github.com/lattner/429b9070918248274f25b714dcfc7619>
> 
> and I have a PR with the first half of the implementation here:
> https://github.com/apple/swift/pull/11501 
> <https://github.com/apple/swift/pull/11501>
> 
> The piece that is missing is code generation support.
> 
> -Chris
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> <https://lists.swift.org/mailman/listinfo/swift-evolution>
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to