<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div><blockquote type="cite" class=""><div class="">On Sep 7, 2017, at 1:04 AM, Howard Lovatt via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">I would argue that given:<div class=""><br class=""></div><div class=""><span style="color:rgb(80,0,80);font-size:12.8px" class="">&nbsp; &nbsp; foo()</span><br style="color:rgb(80,0,80);font-size:12.8px" class=""><span style="color:rgb(80,0,80);font-size:12.8px" class="">&nbsp; &nbsp; await bar()</span><br style="color:rgb(80,0,80);font-size:12.8px" class=""><span style="color:rgb(80,0,80);font-size:12.8px" class="">&nbsp; &nbsp; baz()</span><br class=""></div><div class=""><span style="color:rgb(80,0,80);font-size:12.8px" class=""><br class=""></span></div><div class=""><span style="color:rgb(80,0,80);font-size:12.8px" class="">That foo and baz should run on the same queue&nbsp;</span><span style="color:rgb(80,0,80);font-size:12.8px" class="">(using queue in the GCD sense)&nbsp;</span><span style="color:rgb(80,0,80);font-size:12.8px" class="">but bar should determine which queue it runs on. I say this because:</span></div><div class=""><ol class=""><li class="">foo and baz are running synchronously with respect to each other (though they could be running asynchronously with respect to some other process if all the lines shown are inside an async function).</li><li class="">bar is running asynchronously relative to foo and baz, potentially on a different queue.</li></ol></div></div></div></blockquote><div><br class=""></div><div>This isn't true, in the code above, foo() bar() and baz() all execute serially (synchronously is a weird word to use here IMO).</div><div>Serial code that you write with or without async/await in the middle will run serially independently from where it physically executes.</div><div><br class=""></div><div>And for the record I do agree with Chris that by default foo() and baz() should execute on the same context. This is quite tricky if the caller is a pthread though, and the three possibilities I see for this on a manually made thread are:</div><div>- we assert at runtime</div><div>- await synchronously blocks in that case</div><div>- baz() doesn't execute on the thread</div><div><br class=""></div><div>I think the 3rd one is a non starter, that (1) would be nice but may prove impractical. a (4) would be to require for people making manual threads and using async/await to drain some thing themselves from that thread through an event loop of theirs. But the danger or (4) is that if the client doesn't do it, then the failure mode is silent.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="">I say bar is potentially on a different queue because the user of bar, the person who wrote these 3 lines above, cannot be presumed to be the writer of foo, baz, and particularly not bar and therefore have no detailed knowledge about which queue is appropriate.</div><div class=""><br class=""><div class="">Therefore I would suggest either using a Future or expanding async so that you can say:</div></div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; func bar() async(qos: .userInitiated) { ... }</div><div class=""><br class=""></div><div class="">You also probably need the ability to specify a timeout and queue type, e.g.:</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp;func bar() async(type: .serial,&nbsp;qos: .utility, timeout: .seconds(10)) throws { ... }</div><div class=""><br class=""></div><div class="">If a timeout is specified then await would have to throw to enable the timeout, i.e. call would become:</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp;try await bar()</div><div class=""><br class=""></div><div class="">Defaults could be provided for qos (.default works well), timeout (1 second works well), and type (.concurrent works well).</div><div class=""><br class=""></div><div class="">However a Future does all this already :).</div></div><div class="gmail_extra"><br clear="all" class=""><div class=""><div class="gmail_signature" data-smartmail="gmail_signature">&nbsp; -- Howard.<br class=""></div></div>
<br class=""><div class="gmail_quote">On 7 September 2017 at 15:13, David Hart via swift-evolution <span dir="ltr" class="">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt;</span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=""><br class="">
<br class="">
&gt; On 7 Sep 2017, at 07:05, Chris Lattner via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class="">
&gt;<br class="">
&gt;<br class="">
&gt;&gt; On Sep 5, 2017, at 7:31 PM, Eagle Offshore via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class="">
&gt;&gt;<br class="">
&gt;&gt; OK, I've been watching this thing for a couple weeks.<br class="">
&gt;&gt;<br class="">
&gt;&gt; I've done a lot of GCD network code.&nbsp; Invariably my completion method starts with<br class="">
&gt;&gt;<br class="">
&gt;&gt; dispatch_async(queue_want_to_<wbr class="">handle_this_on,....)<br class="">
&gt;&gt;<br class="">
&gt;&gt; Replying on the same queue would be nice I guess, only often all I need to do is update the UI in the completion code.<br class="">
&gt;&gt;<br class="">
&gt;&gt; OTOH, I have situations where the reply is complicated and I need to persist a lot of data, then update the UI.<br class="">
&gt;&gt;<br class="">
&gt;&gt; So honestly, any assumption you make about how this is supposed to work is going to be wrong about half the time unless....<br class="">
&gt;&gt;<br class="">
&gt;&gt; you let me specify the reply queue directly.<br class="">
&gt;&gt;<br class="">
&gt;&gt; That is the only thing that works all the time.&nbsp; Even then, I'm very apt to make the choice to do some of the work off the main thread and then queue up the minimal amount of work onto the main thread.<br class="">
&gt;<br class="">
&gt; I (think that I) understand what you’re saying here, but I don’t think that we’re talking about the same thing.<br class="">
&gt;<br class="">
&gt; You seem to be making an argument about what is most *useful* (being able to vector a completion handler to a specific queue), but I’m personally concerned about what is most *surprising* and therefore unnatural and prone to introduce bugs and misunderstandings by people who haven’t written the code.&nbsp; To make this more concrete, shift from the “person who writes to code” to the “person who has to maintain someone else's code”:<br class="">
&gt;<br class="">
&gt; Imagine you are maintaining a large codebase, and you come across this (intentionally abstract) code:<br class="">
&gt;<br class="">
&gt;&nbsp; &nbsp; foo()<br class="">
&gt;&nbsp; &nbsp; await bar()<br class="">
&gt;&nbsp; &nbsp; baz()<br class="">
&gt;<br class="">
&gt; Regardless of what is the most useful, I’d argue that it is only natural to expect baz() to run on the same queue/thread/execution-context as foo and bar.&nbsp; If, in the same model, you see something like:<br class="">
&gt;<br class="">
&gt;&nbsp; &nbsp; foo()<br class="">
&gt;&nbsp; &nbsp; await bar()<br class="">
&gt;&nbsp; &nbsp; anotherQueue.async {<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; baz()<br class="">
&gt;&nbsp; &nbsp; }<br class="">
<br class="">
</span>Couldn’t it end up being:<br class="">
<br class="">
foo()<br class="">
await bar()<br class="">
await anotherQueue.async()<br class="">
// on another queue<br class="">
<div class="HOEnZb"><div class="h5"><br class="">
&gt; Then it is super clear what is going on: an intentional queue hop from whatever foo/bar are run on to anotherQueue.<br class="">
&gt;<br class="">
&gt; I interpret your email as arguing for something like this:<br class="">
&gt;<br class="">
&gt;&nbsp; &nbsp; foo()<br class="">
&gt;&nbsp; &nbsp; await(anotherQueue) bar()<br class="">
&gt;&nbsp; &nbsp; baz()<br class="">
&gt;<br class="">
&gt; I’m not sure if that’s exactly the syntax you’re arguing for, but anything like this presents a number of challenges:<br class="">
&gt;<br class="">
&gt; 1) it is “just sugar” over the basic model, so we could argue to add it at any time (and would argue strongly to defer it out of this round of discussions).<br class="">
&gt;<br class="">
&gt; 2) We’d have to find a syntax that implies that baz() runs on anotherQueue, but bar() runs on the existing queue.&nbsp; The syntax I sketched above does NOT provide this indication.<br class="">
&gt;<br class="">
&gt; -Chris<br class="">
&gt;<br class="">
&gt;<br class="">
&gt; ______________________________<wbr class="">_________________<br class="">
&gt; swift-evolution mailing list<br class="">
&gt; <a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">
&gt; <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/<wbr class="">mailman/listinfo/swift-<wbr class="">evolution</a><br class="">
<br class="">
______________________________<wbr class="">_________________<br class="">
swift-evolution mailing list<br class="">
<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/<wbr class="">mailman/listinfo/swift-<wbr class="">evolution</a><br class="">
</div></div></blockquote></div><br class=""></div>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>