[swift-evolution] New async keyword usage

BJ Homer bjhomer at gmail.com
Fri Aug 25 17:49:06 CDT 2017


> I'm not sure why it's understood as all or nothing, AFAICU, await is just a way to block the current queue and wait for a result from an async function.
> beginAsync is a way to make sure we don't block the current execution queue.

Await does not block the current queue. You can imagine that it gathers up the rest of the function after the ‘await’ line and moves it into a callback. That is, it turns this:

let x = await somethingThatTakesALongTime()
print(“Congratulations, we got x”)
print(“x: \(x)”)

into something like this:

somethingThatTakesALongTime(completion: { (x) in
   print(“Congratulations, we got x”)
   print(“x: \(x)”)
})

It does not block the current queue, though. The current queue keeps going on with whatever it was doing before. When the ‘await'ed call finished, it is scheduled back on a queue to continue running.

-BJ

> On Aug 25, 2017, at 4:39 PM, Florent Vilmart via swift-evolution <swift-evolution at swift.org> wrote:
> 
> 
> On 25 août 2017 18:31 -0400, Jonathan Hull <jhull at gbis.com>, wrote:
>> But then it would need to be called with await under the current proposal, meaning that either:
>> 
>> • b would await the calculation of a
>> 
>> beginAsync {
>> let a = await longCalculationA()
>> let b = await longCalculationB() //This only calculates when a is finished
>> } 
> why would it? the async modifier could very well be used to transform a sync function into an async one, dispatching on a defined queue returning the 'Future' and resolving once the function completes.
> 
> I'm not sure why it's understood as all or nothing, AFAICU, await is just a way to block the current queue and wait for a result from an async function.
> beginAsync is a way to make sure we don't block the current execution queue.
> 
> something like
> 
> let a = await async longSynchrounousCall() would block the current execution queue (because await) but the execution of the longSynchronousCall() would be on a separate queue / block.
> 
> The question lays more in where the calls are executed, either they are dispatched after, current block is suspended, runloop continues, and then the block is re-entered upon returning.  that would lead to some weird executions flows.
> 
>> 
>> • or b would be executed while a is awaiting, but a and b would be in different scopes
>> 
>> beginAsync{
>> let a = await longCalculationA()
>> }
>> beginAsync{
>> let b = await longCalculationB() //We can’t see ‘a’ anymore
>> }
>> //We can’t see ‘a’ or ‘b’ here to use them
>> 
>> We could, also implement some sort of future, and then re-write our functions to take advantage of it, but this misses out on numerous compiler optimizations and requires our functions to be written with futures in mind.  In my example, the functions can just be written as async, and they don’t care whether they are called with async or await.
>> 
>> Thanks,
>> Jon
>> 
>>> On Aug 25, 2017, at 3:13 PM, Florent Vilmart <florent at flovilmart.com <mailto:florent at flovilmart.com>> wrote:
>>> 
>>> be doesn't wait if it's defined as 
>>> 
>>> func longCalculationB() async -> SomeType 
>>> 
>>> which would be helpful if it's a long calculation, 
>>> 
>>> in the case it's
>>> 
>>> func longCalculationB() -> SomeType 
>>> 
>>> That would probably be valid to put the async keyword front even though I would not be a big fan of that as you'd be executing on an indefinite queue a calculation that may not be thread safe.
>>> 
>>> async would be in that case a wrapper around dispatch_async  + semaphore
>>> 
>>> 
>>> On 25 août 2017 18:08 -0400, Jonathan Hull <jhull at gbis.com <mailto:jhull at gbis.com>>, wrote:
>>>> Why wouldn’t b wait for a in this example?  If it is using futures, those aren’t available in the current proposal.
>>>> 
>>>>> On Aug 25, 2017, at 3:02 PM, Florent Vilmart <florent at flovilmart.com <mailto:florent at flovilmart.com>> wrote:
>>>>> 
>>>>> Probably with:
>>>>> 
>>>>> let a = longCalculationA() 
>>>>> let b = longCalculationB() //b doesn’t wait for a to complete before starting
>>>>> let c = longCalculationC() //c doesn’t wait for a or b
>>>>> let (aResult, bResult, cResult) = await Future.collect(a, b, c) //waits until a, b, and c are all available
>>>>> 
>>>>> On 25 août 2017 17:48 -0400, wrote:
>>>>>> 
>>>>>> let a = async longCalculationA()
>>>>>> let b = async longCalculationB() //b doesn’t wait for a to complete before starting
>>>>>> let c = async longCalculationC() //c doesn’t wait for a or b
>>>>>> let result = await combineCalculations(a: a, b: b, c: c) //waits until a, b, and c are all available
>>>> 
>> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170825/5fa39b5d/attachment.html>


More information about the swift-evolution mailing list