<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Proposal Link: <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0161-key-paths.md" class="">https://github.com/apple/swift-evolution/blob/master/proposals/0161-key-paths.md</a><div class=""><div class=""><br class="">Hello Swift community,<br class=""><br class="">The review of SE-0161 “Smart KeyPaths: Better Key-Value Coding for Swift” ran from March 30...April 5, 2017. The proposal was very well-received *except* that reviewers felt that the <font face="Menlo" class="">#keyPath</font> syntax was far too heavy for this new language construct, and preferred the lighter-weight syntax of the pre-review drafts. This proposal is <b class="">returned for revision</b> to address the syntax.</div><div class=""><br class=""></div><div class="">The heavyweight <font face="Menlo" class="">#keyPath</font> syntax was requested by the core team after reviewing earlier drafts, which used a far lighter syntax:</div><div class=""><br class=""></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>// (Rejected) syntax from pre-review drafts</font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let firstFriendsNameKeyPath = Person.friends[0].name</font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>print(luke[keyPath: .friends[0].name])</font></div><div class=""><br class=""></div><div class="">The core team’s specific concern was that these key path expressions (e.g., <font face="Menlo" class="">Person.friends[0].name</font>) don’t make it sufficiently clear that the actual property accesses are being delayed, and that the contextual cues (“<font face="Menlo" class="">Person.</font>" vs. “<font face="Menlo" class="">luke.</font>”) are insufficient to disambiguate for the human reader. Hence, the request for a different (more explicit) syntax.</div><div class=""><br class=""></div><div class="">Reviewers rightly point out that it is natural for key-paths to use the same syntax as unapplied instance method references, e.g., <font face="Menlo" class="">Person.someInstanceMethod</font> produces a value of some function type with the “Self” type curried, e.g.,<font face="Menlo" class=""> (Person) -> (param-types) -> result-type</font>. The core team agrees with this sentiment. The core team also felt that Swift’s existing unapplied method references suffer from the same clarity problems as the initial key-path syntax, i.e., that it isn’t sufficiently clear that the actual application of “self” is being delayed.</div><div class=""><br class=""></div><div class="">The core team has a specific proposal: use the backslash (‘<font face="Menlo" class="">\</font>’) to as a leading indicator for key paths. Specifically,</div><div class=""><br class=""></div><div class=""><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>// Proposed syntax for second revision</font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>let firstFriendsNameKeyPath = \Person.friends[0].name</font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>print(luke[keyPath: \.friends[0].name])</font></div></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class="">The backslash is a visual cue that the actual application of this chain of property references is delayed, eliminating ambiguities, yet is still quite lightweight and feels “first-class” in the language.</div><div class=""><br class=""></div><div class="">The core team felt that, in the future, the backslash should also be used for unapplied instance method references, to match the proposed syntax for key paths and improve clarity for this non obvious feature. This change could be staged in as a revision to the accepted-but-never-implemented <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0042-flatten-method-types.md" class="">SE-0042: Flattening the function type of unapplied method references</a>, e.g.,</div><div class=""><br class=""></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>// Proposed future syntax for unapplied instance method references</font></div><div class=""><font face="Menlo" class=""> class Person {</font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">        </span> func instanceMethod(_: String) -> Int { … }</font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let f1 = Person.instanceMethod // to-be-deprecated; produces a value of type (Person) -> (String) -> Int</font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let f2 = \Person.instanceMethod // to-be-introduced via a revised SE-0042: produces a value of type (Person, String) -> Int</font></div><div class=""><br class=""></div><div class="">Such an approach gives us a way to stage in SE-0042 and get to eventual consistency between key paths and unapplied instance method references.</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>- Doug</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>Review Manager</div><div class=""><br class=""></div><div class=""><br class=""><br class=""><br class=""><br class=""><br class=""></div></div></body></html>