<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=""><br class=""><div><blockquote type="cite" class=""><div class="">On Apr 20, 2016, at 4:47 PM, Chris Lattner <<a href="mailto:clattner@apple.com" class="">clattner@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">On Apr 20, 2016, at 12:31 PM, David Owens II via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<div class=""><blockquote type="cite" class=""><div class=""><meta http-equiv="Content-Type" content="text/html charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">This is similar to another concern I raised with functions and being able to essentially erase the function argument names and apply two different named parameters just because their types match.<div class=""><br class=""></div><div class="">It seems reasonable to me that you can go from (x: Int, y: Int) => (Int, Int). However, going from (x: Int, y: Int) => (a: Int, b: Int) feels somewhat odd. Yes, the types can obviously slot in there fine, but how much importance do the labels for the types bring to the table?</div><div class=""><br class=""></div><div class="">Similarly, should this (Int, Int) => (x: Int, y: Int) be allowed through an implicit means? If so, then it's really just an intermediate step for (x: Int, y: Int) => (a: Int, b: Int) working.</div></div></div></blockquote><div class=""><br class=""></div><div class="">I completely agree, I think it makes sense to convert from unlabeled to labeled (or back) but not from “labeled" to "differently labeled”.</div><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">So what matters more, type signatures or label names?</div><div class=""><br class=""></div><div class="">Here's an example:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Menlo" class="">typealias Functor = (left: Int, right: Int) -> Int</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">func hi(x: Int, y: Int, fn: Functor) -> Int {</font></div><div class=""><font face="Menlo" class=""> return fn(left: x, right: y)</font></div><div class=""><font face="Menlo" class="">}</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">hi(1, y: 2, fn: +)</font></div><div class=""><font face="Menlo" class="">hi(1, y: 2, fn: *)</font></div></blockquote><div class=""><br class=""></div><div class="">If we say that the parameter names are indeed vital, then the above code cannot work as the operators that match the type signature are defined as: </div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Menlo" class="">public func +(lhs: Int, rhs: Int) -> Int</font></div></blockquote><div class=""><br class=""></div><div class="">Obviously, given a name to the parameter brings clarity and can be self documenting, but if we want the above to work while making names just as vital as the type signature, then we need to declare `Functor` as such:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div class=""><font face="Menlo" class="">typealias Functor = (_ left: Int, _ right: Int) -> Int</font></div></div></blockquote><div class=""><br class=""></div><div class="">However, that's not even legal code today, and even if it were, is that really better?</div></div></div></blockquote></div><br class=""><div class="">I don’t think this follows, since operator parameters are always unlabeled. I suspect we don’t reject it, but I’d be in favor of rejecting:</div><div class=""><br class=""></div><div class="">func +(lhs <b class="">xyz</b>: Int, rhs <b class="">abc</b>: Int) -> Int { }</div></div></div></blockquote><div><br class=""></div></div>So maybe I think about this incorrectly, but I always think of any parameter without an explicit label to have one that is equal to the parameter name. So these two functions signatures would be equivalent:<div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Menlo" class="">func sum1(lhs: Int, rhs: Int) -> Int</font></div><div class=""><div class=""><font face="Menlo" class="">func sum2(lhs lhs: Int, rhs rhs: Int) -> Int</font></div></div><div class=""><font face="Menlo" class=""><br class=""></font></div></blockquote>It’s only when you explicit “erase” the label where there is none:<div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div class=""><font face="Menlo" class="">func sum(_ lhs: Int, _ rhs: Int) -> Int</font></div></div><div class=""><font face="Menlo" class=""><br class=""></font></div></blockquote><div class=""><div class=""></div></div><div class="">So back to the example above, it’s still somewhat odd that all of these are valid:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><font face="Menlo" class="">hi(1, y: 2, fn: sum1)</font></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><span style="font-family: Menlo;" class="">hi(1, y: 2, fn: sum2)</span></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><span style="font-family: Menlo;" class="">hi(1, y: 2, fn: sum) // makes the most sense, no label to labeled promotion</span></blockquote><div class=""><font face="Menlo" class=""><br class=""></font></div><div class="">But if we did reject the differently labeled version, that would mean that we would need to declare the `Functor` above as:</div><div class=""><br class=""></div><div class=""><blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px;" class=""><font face="Menlo" class="">typealias Functor = (Int, Int) -> Int</font></blockquote></div><div class=""><br class=""></div><div class="">Is that better? I’m not terribly convinced that it is.</div><div class=""><br class=""></div><div class="">If `Functor` keeps the labels, I suspect it would just lead to additional boiler-plate code that would look like:</div><div class=""><br class=""></div><div class=""><div class=""><blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px;" class=""><font face="Menlo" class="">typealias Functor = (left: Int, right: Int) -> Int</font></blockquote></div><blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px;" class=""><font face="Menlo" class=""><br class=""></font></blockquote><blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px;" class=""><font face="Menlo" class="">hi(1, y: 2, fn: { left, right in sum1(lhs: left, rhs: right) })</font></blockquote></div><div class=""><br class=""></div><div class="">While it does seem technically correct, is that really the kind of code we want in Swift? </div><div class=""><br class=""></div><div class="">-David</div></body></html>