<div dir="ltr"><div><font color="#bb2ca2" face="Menlo"><span style="font-size:11px">func</span></font><font face="Menlo"><span style="font-size:11px"> call(completion: (() </span></font><span style="font-family:Menlo;font-size:11px;color:rgb(187,44,162)">throws</span><span style="font-family:Menlo;font-size:11px"> -&gt; Value) -&gt; Void) { ... }</span><br></div><div><span style="font-family:Menlo;font-size:11px"><br></span></div><div>With completion handlers I quite like this approach, I don&#39;t think anyone has brought it up yet. The nice thing is that it&#39;s concise, consistent and you can do it with existing functionality. You can also defer expensive calculations if you only care that it did complete, not whether it succeeded.</div><div><br></div><div><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)">// example:</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:rgb(187,44,162)">typealias</span> Value = <span style="color:rgb(112,61,170)">Int</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:rgb(187,44,162)">enum</span> SomeError: <span style="color:rgb(112,61,170)">ErrorType</span> { <span style="color:rgb(187,44,162)">case</span> Failed }</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:rgb(187,44,162)">var</span> queue = <span style="color:rgb(112,61,170)">Array</span>&lt;()-&gt;<span style="color:rgb(112,61,170)">Void</span>&gt;()</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:rgb(187,44,162)">func</span> doItLater(shouldFail: <span style="color:rgb(112,61,170)">Bool</span>, completion: (() <span style="color:rgb(187,44,162)">throws</span> -&gt; <span style="color:rgb(79,129,135)">Value</span>) -&gt; <span style="color:rgb(112,61,170)">Void</span>) {</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">    <span style="color:rgb(79,129,135)">queue</span>.<span style="color:rgb(61,29,129)">append</span> {</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">        <span style="color:rgb(187,44,162)">if</span> shouldFail {</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">            completion { <span style="color:rgb(187,44,162)">throw</span> <span style="color:rgb(79,129,135)">SomeError</span>.<span style="color:rgb(49,89,93)">Failed</span> }</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">        }</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">        <span style="color:rgb(187,44,162)">else</span> {</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">            completion { <span style="color:rgb(39,42,216)">123</span> }</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">        }</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">    }</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">}</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)">// usage:</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(49,89,93)">doItLater<span style="color:rgb(0,0,0)">(</span><span style="color:rgb(187,44,162)">false</span><span style="color:rgb(0,0,0)">) {</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">    <span style="color:rgb(187,44,162)">guard</span> <span style="color:rgb(187,44,162)">let</span> value = <span style="color:rgb(187,44,162)">try</span>? $0() <span style="color:rgb(187,44,162)">else</span> { <span style="color:rgb(187,44,162)">return</span> }</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(209,47,27)"><span style="color:rgb(0,0,0)">    </span><span style="color:rgb(61,29,129)">print</span><span style="color:rgb(0,0,0)">(</span>&quot;it worked! <span style="color:rgb(0,0,0)">\</span>(<span style="color:rgb(0,0,0)">value</span>)&quot;<span style="color:rgb(0,0,0)">)</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">}</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(49,89,93)">doItLater<span style="color:rgb(0,0,0)">(</span><span style="color:rgb(187,44,162)">true</span><span style="color:rgb(0,0,0)">) {</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">    <span style="color:rgb(187,44,162)">do</span> {</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">        <span style="color:rgb(61,29,129)">print</span>(<span style="color:rgb(209,47,27)">&quot;it worked! </span>\<span style="color:rgb(209,47,27)">(</span><span style="color:rgb(187,44,162)">try</span> $0()<span style="color:rgb(209,47,27)">)&quot;</span>)</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">    }</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">    <span style="color:rgb(187,44,162)">catch</span> {</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">        <span style="color:rgb(61,29,129)">print</span>(<span style="color:rgb(209,47,27)">&quot;it failed </span>\<span style="color:rgb(209,47,27)">(</span>error<span style="color:rgb(209,47,27)">)&quot;</span>)</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">    }</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">}</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:rgb(79,129,135)">queue</span>.<span style="color:rgb(61,29,129)">forEach</span> { $0() }</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><br></p></div><div>P.S.</div><div>Sorry, I&#39;ve resurrected this from the archive as I joined the mailing list too late.</div><div><br></div><div>In-Reply-To: &lt;<a href="mailto:C96096A9-E9F7-4566-A412-0E9E3B724DC9@fifthace.com">C96096A9-E9F7-4566-A412-0E9E3B724DC9@fifthace.com</a>&gt;<br></div><div>Message-ID: &lt;CAN9tzpDy6-_gy=<a href="mailto:GV_6oR7_Nr3P6Mrk7pdEjFwS9xtDjmoJN_Uw@mail.gmail.com">GV_6oR7_Nr3P6Mrk7pdEjFwS9xtDjmoJN_Uw@mail.gmail.com</a>&gt;<br></div><div><br></div><div>I can&#39;t work out how to get gmail to set the headers. I apologise I&#39;m a mailman noob.</div><br>&gt; There&#39;s a concurrency proposal that discusses various options here:<br>&gt; <a href="https://github.com/apple/swift/blob/master/docs/proposals/Concurrency.rst">https://github.com/apple/swift/blob/master/docs/proposals/Concurrency.rst</a><br>&gt; <br>&gt; I like the idea of using try-catch for asynchronous error handling, but<br>&gt; don&#39;t think that defers needs to annotate throws. With a language-level<br>&gt; async/await model we&#39;d get deferred catching for free:<br>&gt; <br>&gt;     class Request {<br>&gt;         async func fetch() throws -&gt; Response {}<br>&gt;     }<br>&gt; <br>&gt;     try {<br>&gt;         let response = try await request.fetch()<br>&gt;     } catch {<br>&gt;         // handle error<br>&gt;     }<br>&gt; <br>&gt; The &quot;try await ?&quot; is a bit wordy, though.<br>&gt; <br>&gt; On Fri, Dec 4, 2015 at 2:19 PM, Sean Heber &lt;sean at <a href="http://fifthace.com">fifthace.com</a>&gt; wrote:<br>&gt; <br>&gt;&gt; I think that the code duplication issue is more of an API design side<br>&gt;&gt; effect. If the API was designed with a 3rd block for when it is ?done?<br>&gt;&gt; regardless of error, then you could put that shared code there - but I<br>&gt;&gt; would imagine that?d be out of the scope of Swift itself. What I often do<br>&gt;&gt; in these situations is just make a local function that does the shared<br>&gt;&gt; stuff and then call it from both blocks:<br>&gt;&gt;<br>&gt;&gt; func finished() {<br>&gt;&gt;           activityIndicator.stopAnimating()<br>&gt;&gt;           button.enabled = true<br>&gt;&gt;           tableView.hidden = false<br>&gt;&gt; }<br>&gt;&gt;<br>&gt;&gt; request.fetch(withCompletionHandler: { result in<br>&gt;&gt;           finished()<br>&gt;&gt;           use(result)<br>&gt;&gt;      }, errorHandler: { error in<br>&gt;&gt;           finished()<br>&gt;&gt;           handleFetchError(error)<br>&gt;&gt;      })<br>&gt;&gt;<br>&gt;&gt; l8r<br>&gt;&gt; Sean<br>&gt;&gt;<br>&gt;&gt;<br>&gt;&gt;&gt; On Dec 4, 2015, at 1:13 PM, Dan Stenmark &lt;daniel.j.stenmark at <a href="http://gmail.com">gmail.com</a>&gt;<br>&gt;&gt;wrote:<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; Hey Alex!<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; I completely agree that the double-block approach is advantageous for<br>&gt;&gt;its reduced unwrapping, but the only issue I have is that, when applied in<br>&gt;&gt;production, it typically leads to duplicate code.<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; request.fetch(withCompletionHandler: { result in<br>&gt;&gt;&gt;           activityIndicator.stopAnimating()<br>&gt;&gt;&gt;           button.enabled = true<br>&gt;&gt;&gt;           tableView.hidden = false<br>&gt;&gt;&gt;<br>&gt;&gt;&gt;           use(result)<br>&gt;&gt;&gt;<br>&gt;&gt;&gt;           print( ?Foo!? )<br>&gt;&gt;&gt;<br>&gt;&gt;&gt;      }, errorHandler: { error in<br>&gt;&gt;&gt;           activityIndicator.stopAnimating()<br>&gt;&gt;&gt;           button.enabled = true<br>&gt;&gt;&gt;           tableView.hidden = false<br>&gt;&gt;&gt;<br>&gt;&gt;&gt;           // Don?t need to force unwrap `error`.<br>&gt;&gt;&gt;           handleFetchError(error)<br>&gt;&gt;&gt;<br>&gt;&gt;&gt;           print( ?Foo!? )<br>&gt;&gt;&gt;<br>&gt;&gt;&gt;      })<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; The same issue is present in the aforementioned deferred throw concept.<br>&gt;&gt;There?re certainly ways to mitigate the problem, but no practical way of<br>&gt;&gt;eliminating it altogether.  I?m personally leaning towards an evolution of<br>&gt;&gt;the Enum-based approach for this very reason, but if a solution can be<br>&gt;&gt;figured out to remove such code duplication, I?d happily adopt<br>&gt;&gt;double-blocks.<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; Dan<br>&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt; On Dec 4, 2015, at 10:20 AM, Vinicius Vendramini &lt;vinivendra at <a href="http://gmail.com">gmail.com</a>&gt;<br>&gt;&gt;wrote:<br>&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt; I really like the idea of using try/catches, it seems like a more<br>&gt;&gt;swifty approach. However, I&#39;d prefer to do it in a way that doesn&#39;t add a<br>&gt;&gt;new syntax.<br>&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt; Also, I agree with Alex, the second options seems the best of those<br>&gt;&gt;alternatives (if it were done without trailing closures.)<br>&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt; On Dec 4, 2015, at 12:21 PM, Sean Heber &lt;sean at <a href="http://fifthace.com">fifthace.com</a>&gt; wrote:<br>&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt; What if there was a possibility for a deferred throw?<br>&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt; For example, imagine the fetch function was something like this:<br>&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt; func fetch(withCompletionHandler: (Result) -&gt; ()) defer throws {}<br>&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt; And to call it, you?d wrap it in a try with a new kind of catch:<br>&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt; do {<br>&gt;&gt;&gt;&gt;&gt; try request.fetch() { result in ? }<br>&gt;&gt;&gt;&gt;&gt; } defer catch (? pattern) {<br>&gt;&gt;&gt;&gt;&gt; }<br>&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt; So what the language would do then is treat all of the ?defer catch?<br>&gt;&gt;blocks as closures and pass them along with calls to ?defer throws?<br>&gt;&gt;functions in the same context. When they throw, they would then run those<br>&gt;&gt;blocks as if you had passed them along manually in the double block style.<br>&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt; The context to throw back to would need to be capture-able by the<br>&gt;&gt;function body for fetch() so that if it encounters an error some time later<br>&gt;&gt;it would know where to throw it to. Perhaps the easiest way would be to<br>&gt;&gt;create a closure that throws like so:<br>&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt; func fetch(withCompletionHandler: (Result) -&gt; ()) defer throws {<br>&gt;&gt;&gt;&gt;&gt; var context = FetchContext()<br>&gt;&gt;&gt;&gt;&gt; context.completionHandler = withCompletionHandler<br>&gt;&gt;&gt;&gt;&gt; context.errorHandler = { reason in throw RequestError(reason) }<br>&gt;&gt;&gt;&gt;&gt; self.pending.append(context)<br>&gt;&gt;&gt;&gt;&gt; context.start()<br>&gt;&gt;&gt;&gt;&gt; }<br>&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt; Under the hood the ?throw? captured in the closure would also be<br>&gt;&gt;carrying along the context needed to route that error back to the expected<br>&gt;&gt;defer catch block.<br>&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt; l8r<br>&gt;&gt;&gt;&gt;&gt; Sean<br>&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt;&gt;&gt; On Dec 4, 2015, at 10:57 AM, Alex Migicovsky &lt;migi at <a href="http://apple.com">apple.com</a>&gt; wrote:<br>&gt;&gt;&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; On Dec 3, 2015, at 2:15 PM, Douglas Gregor &lt;dgregor at <a href="http://apple.com">apple.com</a>&gt;<br>&gt;&gt;wrote:<br>&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; On Dec 3, 2015, at 12:32 PM, Dan Stenmark &lt;<br>&gt;&gt;daniel.j.stenmark at <a href="http://gmail.com">gmail.com</a>&gt; wrote:<br>&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; There?s a some of debate in the community regarding best practice<br>&gt;&gt;for asynchronous completion callbacks.  These practices include:<br>&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; - Single Block w/ Mutually Exclusive Result and Error Objects (the<br>&gt;&gt;current standard convention in Cocoa, though originally designed with<br>&gt;&gt;Objective-C in mind)<br>&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; - Double Block (one for success, one for failure)<br>&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; - Swift Enum w/ Associated Objects (as described here:<br>&gt;&gt;<a href="http://www.developerdave.co.uk/2015/09/better-completion-handlers-in-swift/">http://www.developerdave.co.uk/2015/09/better-completion-handlers-in-swift/</a><br>&gt;&gt;)<br>&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; Even prior to Swift, Apple?s code guidelines never explicitly<br>&gt;&gt;addressed this topic.  Going forward into the brave new world of Swift, are<br>&gt;&gt;there going to be new preferred API design guidelines for this?<br>&gt;&gt;&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt;&gt;&gt; This is a great point, and there are a number of other issues<br>&gt;&gt;related to callbacks/closure arguments that would benefit from guidelines.<br>&gt;&gt;For example, I&#39;ve seen the ?Double Block? case where the second block ends<br>&gt;&gt;up being a trailing closure, which makes for non-intuitive uses.<br>&gt;&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt;&gt; Hi Dan!<br>&gt;&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt;&gt; I think guidelines in this area would be great.<br>&gt;&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt;&gt; Here are the tradeoffs I think we have for each approach:<br>&gt;&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt;&gt; 1) The single block approach means you?d code against an optional<br>&gt;&gt;result and an optional error, making it easy to write invalid code (see<br>&gt;&gt;example in #2). With the single block you can use trailing closure syntax<br>&gt;&gt;coherently. I think most ObjC APIs use this approach since it works well in<br>&gt;&gt;ObjC.<br>&gt;&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt;&gt; 2) As Doug mentioned, the double block can be inconvenient / awkward<br>&gt;&gt;but it does produce more correct code.<br>&gt;&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt;&gt; Doug: maybe we can limit using trailing closures from being used if<br>&gt;&gt;the 2nd to last parameter is also a closure? That would eliminate some<br>&gt;&gt;confusion at the call site.<br>&gt;&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt;&gt; Some ObjC APIs use this approach. One positive aspect of the<br>&gt;&gt;double-block approach is that it always produces code that?s less indented<br>&gt;&gt;than the single block approach. e.g.<br>&gt;&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt;&gt;    /*<br>&gt;&gt;&gt;&gt;&gt;&gt;         Single block.<br>&gt;&gt;&gt;&gt;&gt;&gt;         Trailing closure syntax works well.<br>&gt;&gt;&gt;&gt;&gt;&gt;    */<br>&gt;&gt;&gt;&gt;&gt;&gt;    request.fetch { result, error in<br>&gt;&gt;&gt;&gt;&gt;&gt;         // More indented code since we need to use guard or if let.<br>&gt;&gt;&gt;&gt;&gt;&gt;         guard let result = result else {<br>&gt;&gt;&gt;&gt;&gt;&gt;              // Need to force unwrap `error`.<br>&gt;&gt;&gt;&gt;&gt;&gt;              handleFetchError(error!)<br>&gt;&gt;&gt;&gt;&gt;&gt;              return<br>&gt;&gt;&gt;&gt;&gt;&gt;         }<br>&gt;&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt;&gt;         use(result)<br>&gt;&gt;&gt;&gt;&gt;&gt;    }<br>&gt;&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt;&gt;    /*<br>&gt;&gt;&gt;&gt;&gt;&gt;         Double block.<br>&gt;&gt;&gt;&gt;&gt;&gt;         Trailing closure syntax is awkward here.<br>&gt;&gt;&gt;&gt;&gt;&gt;    */<br>&gt;&gt;&gt;&gt;&gt;&gt;    request.fetch(withCompletionHandler: { result in<br>&gt;&gt;&gt;&gt;&gt;&gt;         use(result)<br>&gt;&gt;&gt;&gt;&gt;&gt;    }, errorHandler: { error in<br>&gt;&gt;&gt;&gt;&gt;&gt;         // Don?t need to force unwrap `error`.<br>&gt;&gt;&gt;&gt;&gt;&gt;         handleFetchError(error)<br>&gt;&gt;&gt;&gt;&gt;&gt;    })<br>&gt;&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt;&gt; 3) Enums with associated values are conceptually nice, but unless we<br>&gt;&gt;have a Result&lt;&gt; or an Either&lt;&gt; in the Standard Library I think most people<br>&gt;&gt;will write one-off enums for each set of methods that return a specific<br>&gt;&gt;kind of result + error. That adds an unnecessary conceptual burden since<br>&gt;&gt;you need to know the type of of the value that?s passed to each callback.<br>&gt;&gt;Also, we don?t have any primarily ObjC APIs that use this approach yet. It<br>&gt;&gt;would also suffer from the same indentation problem as #1 but without the<br>&gt;&gt;?invalid code? problem. If we go this route I think we?d want to map the<br>&gt;&gt;async error ObjC APIs to use this approach similar to what we do with<br>&gt;&gt;non-async error handling.<br>&gt;&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt;&gt; Looking at the tradeoffs I think I prefer #2 if we could limit the<br>&gt;&gt;ability to use a trailing closure for the last parameter. I?d want to look<br>&gt;&gt;at more code with the change though. We should also consider whether we<br>&gt;&gt;should map the single block APIs in ObjC into double block APIs. What do<br>&gt;&gt;you think?<br>&gt;&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt;&gt; Also, with any of these approaches there?s also the question of<br>&gt;&gt;whether we pass ErrorType, NSError, or the specific error type.<br>&gt;&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt;&gt; - Alex<br>&gt;&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt;&gt; _______________________________________________<br>&gt;&gt;&gt;&gt;&gt;&gt; swift-evolution mailing list<br>&gt;&gt;&gt;&gt;&gt;&gt; swift-evolution at <a href="http://swift.org">swift.org</a><br>&gt;&gt;&gt;&gt;&gt;&gt; <a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>&gt;&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;&gt; _______________________________________________<br>&gt;&gt;&gt;&gt;&gt; swift-evolution mailing list<br>&gt;&gt;&gt;&gt;&gt; swift-evolution at <a href="http://swift.org">swift.org</a><br>&gt;&gt;&gt;&gt;&gt; <a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>&gt;&gt;&gt;&gt; _______________________________________________<br>&gt;&gt;&gt;&gt; swift-evolution mailing list<br>&gt;&gt;&gt;&gt; swift-evolution at <a href="http://swift.org">swift.org</a><br>&gt;&gt;&gt;&gt; <a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>&gt;&gt;&gt;<br>&gt;&gt;<br>&gt;&gt; _______________________________________________<br>&gt;&gt; swift-evolution mailing list<br>&gt;&gt; swift-evolution at <a href="http://swift.org">swift.org</a><br>&gt;&gt; <a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>&gt;&gt;</div>