<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hello Swift community,<div class=""><br class=""></div><div class="">Swift 3’s&nbsp;<a href="https://github.com/apple/swift-evolution/blob/master/proposals/0110-distingish-single-tuple-arg.md" class="">SE-0110</a>&nbsp;eliminated the equivalence between function types that accept a single type and function types that take multiple arguments. However, for various&nbsp;<a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170612/037560.html" class="">implementation reasons</a>, the implementation of SE-0110 (as well as the elimination of tuple “splat” behavior in&nbsp;<a href="https://github.com/apple/swift-evolution/blob/master/proposals/0029-remove-implicit-tuple-splat.md" class="">SE-0029</a>) was not fully completed.</div><div class=""><br class=""></div><div class="">Swift 4 implemented more of SE-0110, which caused a fairly serious usability regression, particularly with closures. Here are a few simple examples involving closures that worked in Swift 3 but do not work in Swift 4:</div><div class=""><br class=""></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class=""><div class=""><font face="Menlo" class="">// #1: Works in Swift 3, error in Swift 4</font></div></div><div class=""><div class=""><font face="Menlo" class="">myDictionary.forEach {</font></div></div><div class=""><div class=""><font face="Menlo" class="">&nbsp; print("\($0) -&gt; \($1)")</font></div></div><div class=""><div class=""><font face="Menlo" class="">}</font></div></div><div class=""><div class=""><font face="Menlo" class=""><br class=""></font></div></div><div class=""><div class=""><font face="Menlo" class="">// #2: Works in Swift 3, error in Swift 4</font></div></div><div class=""><div class=""><font face="Menlo" class="">myDictionary.forEach { key, value in</font></div></div><div class=""><div class=""><font face="Menlo" class="">&nbsp; print("\(key) -&gt; \(value)")</font></div></div><div class=""><div class=""><font face="Menlo" class="">}</font></div></div><div class=""><div class=""><font face="Menlo" class=""><br class=""></font></div></div><div class=""><div class=""><font face="Menlo" class="">// #3: Works in Swift 3, error in Swift 4</font></div></div><div class=""><div class=""><font face="Menlo" class="">myDictionary.forEach { (key, value) in</font></div></div><div class=""><div class=""><font face="Menlo" class="">&nbsp; print("\(key) -&gt; \(value)")</font></div></div><div class=""><div class=""><font face="Menlo" class="">}</font></div></div></blockquote><div class=""><br class=""></div><div class="">Similar issues occur with passing multi-argument functions where a tuple argument is expected:</div><div class=""><br class=""></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class=""><div class=""><font face="Menlo" class="">// #4: Works in Swift 3, error in Swift 4</font></div></div><div class=""><div class=""><span class="" style="font-family: Menlo;">_ = zip(array1, array2).map(+)</span></div></div></blockquote><div class=""><br class=""></div><div class="">In all of these cases, it is possible to write a closure that achieves the desired effect, but the result is more verbose and less intuitive:</div><div class=""><br class=""></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class=""><div class=""><font face="Menlo" class="">// Works in both Swift 3 and&nbsp;Swift 4</font></div><div class=""><font face="Menlo" class="">myDictionary.forEach { element in</font></div></div><div class=""><div class=""><font face="Menlo" class="">&nbsp; let (key, value) = element</font></div></div><div class=""><div class=""><font face="Menlo" class="">&nbsp; print("\(key) -&gt; \(value)")</font></div></div><div class=""><div class=""><font face="Menlo" class="">}</font></div></div></blockquote><div class=""><br class=""></div><div class="">The Swift core team feels that these usability regressions are unacceptable for Swift 4. There are a number of promising solutions that would provide a better model for closures and address the usability regression, but fully designing and implementing those are out of scope for Swift 4. &nbsp;Therefore, we will “back out” the SE-0110 change regarding function arguments from Swift 4.</div><div class=""><br class=""></div><div class="">Specifically, when passing an argument value of function type (including closures) to a parameter of function type, a multi-parameter argument function can be passed to a parameter whose function type accepts a single tuple (whose tuple elements match the parameter types of the argument function). Practically speaking, all of the examples #1-#4 will be accepted in both Swift 3 and Swift 4.</div><div class=""><br class=""></div><div class="">We will revisit the design in this area post-Swift 4.</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>- Doug</div><div class=""><br class=""></div></body></html>