> On Aug 23, 2017, at 1:16 PM, Joe Groff via swift-evolution 
> <[email protected]> wrote:
> 
>> 
>> On Aug 21, 2017, at 11:23 PM, Jonathan Hull via swift-evolution 
>> <[email protected]> wrote:
>> 
>> I have seen a lot of examples which use both do and beginAsync:
>> 
>>      beginAsync {
>>              do {
>>                      try await foo()
>>              } catch let e {
>>                      //Handle Error
>>              }
>>      }
>> 
>> I twitch every time I see this, because I thought part of the point of this 
>> was to avoid pyramiding.  It would seem to be an argument for combining try 
>> and await, but as others have pointed out, that causes issues with try? and 
>> try!.  I also really like the explicitness of knowing what could actually 
>> throw errors.
>> 
>> I propose that we instead combine do and beginAsync.  There are 3 cases:
>> 
>> 
>> 1) Just throws (i.e what we have now):
>> 
>>      do {
>>              try foo()
>>      } catch let e {
>>              //Handle Error
>>      }
>> 
>> 
>> 2) Just async (no catch needed):
>> 
>>      do async {
>>              await foo()
>>      }
>> 
>> 
>> 3) Both throws and async:
>> 
>>      do async {
>>              try await foo()
>>      }catch let e{
>>              //It would be a compiler error not to have a catch statement 
>> when there is a try in the do block.
>>      }
>> 
>> 
>> This feels much less messy to me, and will avoid unnecessary pyramids while 
>> still allowing throws and async to be separately declared.
>> 
>> Thanks,
>> Jon
> 
> The proposal is perhaps a bit beginAsync-heavy because it puts a lot of 
> attention on how to adapt existing frameworks to work with coroutines. My 
> feeling is that, in a system with frameworks that have more fully adopted 
> coroutines in all the appropriate places, that you won't need to explicitly 
> enter an async context as frequently since more contexts will already be 
> `async` where they need to be, and that in the situations where you do need 
> to enter a new async context, raw `beginAsync` won't be the best way to do 
> so. `beginAsync` is still going to begin its coroutine body immediately on 
> the current thread, but you're likely to want to associate it with a specific 
> context using something like a version of dispatch_async that takes a `() 
> async -> ()` block. There are also APIs that could provide for coordination 
> with the coroutine, such as a constructor for Future<T> that takes an () 
> async -> T block which is automatically fulfilled by the completion of the 
> block. I'm not against the idea of providing language sugar to make working 
> with coroutines nicer (that is, after all, their whole reason to exist!), but 
> I'm not sure this is the right thing to sugar, and we can always add sugar 
> later once the core language model is set.

Right.  I would only add to this that I'm specifically worried about adding 
features that make blocking the current thread more sugared.

John.
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to