<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hello Swift-friends,<div class=""><br class=""></div><div class="">After more thinking, here is a new proposal, based on my original proposal for #selector for properties but better targeted at the intended use: referencing key-paths. Please let me know what you think:</div><div class=""><br class=""></div><div class=""><h1 style="box-sizing: border-box; font-size: 2.25em; margin-right: 0px; margin-bottom: 16px; margin-left: 0px; line-height: 1.2; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238); color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; background-color: rgb(255, 255, 255); margin-top: 0px !important;" class="">Referencing Objective-C key-paths</h1><ul style="box-sizing: border-box; padding: 0px 0px 0px 2em; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class=""><li style="box-sizing: border-box;" class="">Proposal: <a href="https://github.com/apple/swift-evolution/blob/master/proposals/XXXX-objc-keypaths.md" style="box-sizing: border-box; background-color: transparent; color: rgb(64, 120, 192); text-decoration: none;" class="">SE-XXXX</a></li><li style="box-sizing: border-box;" class="">Author(s): <a href="https://github.com/hartbit" style="box-sizing: border-box; background-color: transparent; color: rgb(64, 120, 192); text-decoration: none;" class="">David Hart</a></li><li style="box-sizing: border-box;" class="">Status: TBD</li><li style="box-sizing: border-box;" class="">Review manager: TBD</li></ul><h2 style="box-sizing: border-box; margin-top: 1em; margin-bottom: 16px; line-height: 1.225; font-size: 1.75em; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238); color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; background-color: rgb(255, 255, 255);" class=""><a id="user-content-introduction" class="anchor" href="https://github.com/hartbit/swift-evolution/tree/objc-keypaths#introduction" aria-hidden="true" style="box-sizing: border-box; background-color: transparent; color: rgb(64, 120, 192); text-decoration: none; display: inline-block; padding-right: 2px; margin-left: -18px; line-height: 1;"><svg aria-hidden="true" class="octicon octicon-link" height="16" role="img" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1h-1c-1.5 0-3-1.69-3-3.5s1.55-3.5 3-3.5h4c1.45 0 3 1.69 3 3.5 0 1.41-0.91 2.72-2 3.25v-1.16c0.58-0.45 1-1.27 1-2.09 0-1.28-1.02-2.5-2-2.5H4c-0.98 0-2 1.22-2 2.5s1 2.5 2 2.5z m9-3h-1v1h1c1 0 2 1.22 2 2.5s-1.02 2.5-2 2.5H9c-0.98 0-2-1.22-2-2.5 0-0.83 0.42-1.64 1-2.09v-1.16c-1.09 0.53-2 1.84-2 3.25 0 1.81 1.55 3.5 3 3.5h4c1.45 0 3-1.69 3-3.5s-1.5-3.5-3-3.5z"></path></svg></a>Introduction</h2><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">In Objective-C and Swift, key-paths used by KVC and KVO are represented as string literals (e.g., <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">"friend.address.streetName"</code>). This proposal seeks to improve the safety and resilience to modification of code using key-paths by introducing a compiler-checked expression.</p><h2 style="box-sizing: border-box; margin-top: 1em; margin-bottom: 16px; line-height: 1.225; font-size: 1.75em; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238); color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; background-color: rgb(255, 255, 255);" class=""><a id="user-content-motivation" class="anchor" href="https://github.com/hartbit/swift-evolution/tree/objc-keypaths#motivation" aria-hidden="true" style="box-sizing: border-box; background-color: transparent; color: rgb(64, 120, 192); text-decoration: none; display: inline-block; padding-right: 2px; margin-left: -18px; line-height: 1;"><svg aria-hidden="true" class="octicon octicon-link" height="16" role="img" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1h-1c-1.5 0-3-1.69-3-3.5s1.55-3.5 3-3.5h4c1.45 0 3 1.69 3 3.5 0 1.41-0.91 2.72-2 3.25v-1.16c0.58-0.45 1-1.27 1-2.09 0-1.28-1.02-2.5-2-2.5H4c-0.98 0-2 1.22-2 2.5s1 2.5 2 2.5z m9-3h-1v1h1c1 0 2 1.22 2 2.5s-1.02 2.5-2 2.5H9c-0.98 0-2-1.22-2-2.5 0-0.83 0.42-1.64 1-2.09v-1.16c-1.09 0.53-2 1.84-2 3.25 0 1.81 1.55 3.5 3 3.5h4c1.45 0 3-1.69 3-3.5s-1.5-3.5-3-3.5z"></path></svg></a>Motivation</h2><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">The use of string literals for key paths is extremely error-prone: there is no checking that the string corresponds to a valid key-path. In a similar manner to the proposal for the Objective-C selector expression <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0022-objc-selectors.md" style="box-sizing: border-box; background-color: transparent; color: rgb(64, 120, 192); text-decoration: none;" class="">SE-0022</a>, this proposal introduces a syntax for referencing compiler-checked key-paths. When the referenced properties and methods are renamed or deleted, the programmer will be notified by a compiler error.</p><h2 style="box-sizing: border-box; margin-top: 1em; margin-bottom: 16px; line-height: 1.225; font-size: 1.75em; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238); color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; background-color: rgb(255, 255, 255);" class=""><a id="user-content-proposed-solution" class="anchor" href="https://github.com/hartbit/swift-evolution/tree/objc-keypaths#proposed-solution" aria-hidden="true" style="box-sizing: border-box; background-color: transparent; color: rgb(64, 120, 192); text-decoration: none; display: inline-block; padding-right: 2px; margin-left: -18px; line-height: 1;"><svg aria-hidden="true" class="octicon octicon-link" height="16" role="img" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1h-1c-1.5 0-3-1.69-3-3.5s1.55-3.5 3-3.5h4c1.45 0 3 1.69 3 3.5 0 1.41-0.91 2.72-2 3.25v-1.16c0.58-0.45 1-1.27 1-2.09 0-1.28-1.02-2.5-2-2.5H4c-0.98 0-2 1.22-2 2.5s1 2.5 2 2.5z m9-3h-1v1h1c1 0 2 1.22 2 2.5s-1.02 2.5-2 2.5H9c-0.98 0-2-1.22-2-2.5 0-0.83 0.42-1.64 1-2.09v-1.16c-1.09 0.53-2 1.84-2 3.25 0 1.81 1.55 3.5 3 3.5h4c1.45 0 3-1.69 3-3.5s-1.5-3.5-3-3.5z"></path></svg></a>Proposed solution</h2><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">Introduce a new expression <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">#keypath</code> that allows one to build a <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">String</code> from a key-path:</p><div class="highlight highlight-source-swift" style="box-sizing: border-box; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);"><pre style="box-sizing: border-box; overflow: auto; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; margin-top: 0px; margin-bottom: 0px; line-height: 1.45; padding: 16px; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-wrap: normal; word-break: normal;" class=""><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">class</span> Person: NSObject {
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">dynamic</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">var</span> firstName: <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">String</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">=</span> <span class="pl-s" style="box-sizing: border-box; color: rgb(24, 54, 145);"><span class="pl-pds" style="box-sizing: border-box;">"</span><span class="pl-pds" style="box-sizing: border-box;">"</span></span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">dynamic</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">var</span> lastName: <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">String</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">=</span> <span class="pl-s" style="box-sizing: border-box; color: rgb(24, 54, 145);"><span class="pl-pds" style="box-sizing: border-box;">"</span><span class="pl-pds" style="box-sizing: border-box;">"</span></span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">dynamic</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">var</span> friends: [Person] <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">=</span> []
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">dynamic</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">var</span> bestFriend: Person?
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">init</span>(firstName: <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">String</span>, lastName: <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">String</span>) {
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">self</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>firstName <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">=</span> firstName
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">self</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>lastName <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">=</span> lastName
}
}
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">let</span> chris <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">=</span> Person(firstName: <span class="pl-s" style="box-sizing: border-box; color: rgb(24, 54, 145);"><span class="pl-pds" style="box-sizing: border-box;">"</span>Chris<span class="pl-pds" style="box-sizing: border-box;">"</span></span>, lastName: <span class="pl-s" style="box-sizing: border-box; color: rgb(24, 54, 145);"><span class="pl-pds" style="box-sizing: border-box;">"</span>Lattner<span class="pl-pds" style="box-sizing: border-box;">"</span></span>)
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">let</span> joe <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">=</span> Person(firstName: <span class="pl-s" style="box-sizing: border-box; color: rgb(24, 54, 145);"><span class="pl-pds" style="box-sizing: border-box;">"</span>Joe<span class="pl-pds" style="box-sizing: border-box;">"</span></span>, lastName: <span class="pl-s" style="box-sizing: border-box; color: rgb(24, 54, 145);"><span class="pl-pds" style="box-sizing: border-box;">"</span>Groff<span class="pl-pds" style="box-sizing: border-box;">"</span></span>)
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">let</span> douglas <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">=</span> Person(firstName: <span class="pl-s" style="box-sizing: border-box; color: rgb(24, 54, 145);"><span class="pl-pds" style="box-sizing: border-box;">"</span>Douglas<span class="pl-pds" style="box-sizing: border-box;">"</span></span>, lastName: <span class="pl-s" style="box-sizing: border-box; color: rgb(24, 54, 145);"><span class="pl-pds" style="box-sizing: border-box;">"</span>Gregor<span class="pl-pds" style="box-sizing: border-box;">"</span></span>)
chris<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>friends <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">=</span> [joe, douglas]
chris<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>bestFriend <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">=</span> joe
#keypath(Person<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>firstName) <span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// => "firstName"</span>
chris<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>valueForKey(#keypath(Person<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>firstName)) <span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// => Chris</span>
#keypath(Person<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>bestFriend<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>lastName) <span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// => "bestFriend.lastName"</span>
chris<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>valueForKeyPath(#keypath(Person<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>bestFriend<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>lastName)) <span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// => Groff</span>
#keypath(Person<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>friends<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>firstName) <span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// => "friends.firstName"</span>
chris<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>valueForKeyPath(#keypath(Person<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>friends<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>firstName)) <span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// => ["Joe", "Douglas"]</span>
</pre></div><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">By having the <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">#keypath</code> expression do the work to form the Objective-C key-path string, we free the developer from having to do the manual typing and get static checking that the key-path exists and is exposed to Objective-C.</p><h2 style="box-sizing: border-box; margin-top: 1em; margin-bottom: 16px; line-height: 1.225; font-size: 1.75em; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238); color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; background-color: rgb(255, 255, 255);" class=""><a id="user-content-impact-on-existing-code" class="anchor" href="https://github.com/hartbit/swift-evolution/tree/objc-keypaths#impact-on-existing-code" aria-hidden="true" style="box-sizing: border-box; background-color: transparent; color: rgb(64, 120, 192); text-decoration: none; display: inline-block; padding-right: 2px; margin-left: -18px; line-height: 1;"><svg aria-hidden="true" class="octicon octicon-link" height="16" role="img" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1h-1c-1.5 0-3-1.69-3-3.5s1.55-3.5 3-3.5h4c1.45 0 3 1.69 3 3.5 0 1.41-0.91 2.72-2 3.25v-1.16c0.58-0.45 1-1.27 1-2.09 0-1.28-1.02-2.5-2-2.5H4c-0.98 0-2 1.22-2 2.5s1 2.5 2 2.5z m9-3h-1v1h1c1 0 2 1.22 2 2.5s-1.02 2.5-2 2.5H9c-0.98 0-2-1.22-2-2.5 0-0.83 0.42-1.64 1-2.09v-1.16c-1.09 0.53-2 1.84-2 3.25 0 1.81 1.55 3.5 3 3.5h4c1.45 0 3-1.69 3-3.5s-1.5-3.5-3-3.5z"></path></svg></a>Impact on existing code</h2><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">The introduction of the <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">#keypath</code> expression has no impact on existing code as it returns a <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">String</code>. It is simply a modification-safe alternative to using literal strings for referencing key-paths.</p><h2 style="box-sizing: border-box; margin-top: 1em; margin-bottom: 16px; line-height: 1.225; font-size: 1.75em; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238); color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; background-color: rgb(255, 255, 255);" class=""><a id="user-content-alternatives-considered" class="anchor" href="https://github.com/hartbit/swift-evolution/tree/objc-keypaths#alternatives-considered" aria-hidden="true" style="box-sizing: border-box; background-color: transparent; color: rgb(64, 120, 192); text-decoration: none; display: inline-block; padding-right: 2px; margin-left: -18px; line-height: 1;"><svg aria-hidden="true" class="octicon octicon-link" height="16" role="img" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1h-1c-1.5 0-3-1.69-3-3.5s1.55-3.5 3-3.5h4c1.45 0 3 1.69 3 3.5 0 1.41-0.91 2.72-2 3.25v-1.16c0.58-0.45 1-1.27 1-2.09 0-1.28-1.02-2.5-2-2.5H4c-0.98 0-2 1.22-2 2.5s1 2.5 2 2.5z m9-3h-1v1h1c1 0 2 1.22 2 2.5s-1.02 2.5-2 2.5H9c-0.98 0-2-1.22-2-2.5 0-0.83 0.42-1.64 1-2.09v-1.16c-1.09 0.53-2 1.84-2 3.25 0 1.81 1.55 3.5 3 3.5h4c1.45 0 3-1.69 3-3.5s-1.5-3.5-3-3.5z"></path></svg></a>Alternatives considered</h2><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">One aspect of the design which seems potentially complicated is the reference to key-paths which include an collection in the middle of the path.</p><div class="highlight highlight-source-swift" style="box-sizing: border-box; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);"><pre style="box-sizing: border-box; overflow: auto; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; margin-top: 0px; margin-bottom: 0px; line-height: 1.45; padding: 16px; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-wrap: normal; word-break: normal;" class="">chris<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>valueForKeyPath(#keypath(Person<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>friends<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>firstName))</pre></div><div style="box-sizing: border-box; margin-top: 0px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255); margin-bottom: 0px !important;" class="">The above example is potentially harder to implement because the argument of <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">#keypath</code> is not a valid Swift expression, compared to the other two examples. An alternative would be to remove the ability to reference those key-paths, making the proposal less useful, but easier to implement.</div></div></body></html>