<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Key paths could be made to work by implementing the protocol in terms of retrieving key paths instead:<div class=""><br class=""></div><div class=""><div style="font-family: SourceSansPro-Regular;" class="">protocol SupplementalKeyPathDispatching {</div><div style="font-family: SourceSansPro-Regular;" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>associatedType KP: PartialKeyPath&lt;Self&gt;</div><div style="font-family: SourceSansPro-Regular;" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>static&nbsp;func&nbsp;supplementalKeyPath(for name: String) -&gt; KP</div><div style="font-family: SourceSansPro-Regular;" class="">}</div><div style="font-family: SourceSansPro-Regular;" class=""><br class=""></div><div style="font-family: SourceSansPro-Regular;" class="">and in your implementation of PyVal:</div><div style="font-family: SourceSansPro-Regular;" class=""><br class=""></div><div style="font-family: SourceSansPro-Regular;" class="">extension PyVal:&nbsp;SupplementalKeyPathDispatching&nbsp;{</div><div style="font-family: SourceSansPro-Regular;" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>static func&nbsp;supplementalKeyPath(for name: String) -&gt; KeyPath&lt;PyVal, PyVal&gt; {</div><div style="font-family: SourceSansPro-Regular;" class=""><span class="Apple-tab-span" style="white-space: pre;">                </span>return \PyVal[dynamicMember: name]</div><div style="font-family: SourceSansPro-Regular;" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>}</div><div style="font-family: SourceSansPro-Regular;" class="">}</div><div style="font-family: SourceSansPro-Regular;" class=""><br class=""></div><div style="font-family: SourceSansPro-Regular;" class="">The compiler then implements two transforms:</div><div style="font-family: SourceSansPro-Regular;" class=""><br class=""></div><div style="font-family: SourceSansPro-Regular;" class=""><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>\PyVal.add_trick</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>// becomes:</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>PyVal.supplementalKeyPath(for: "add_trick")</div></div><div style="font-family: SourceSansPro-Regular;" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>// returns key path \PyVal[dynamicMember: name]</div><div style="font-family: SourceSansPro-Regular;" class=""><br class=""></div><div style="font-family: SourceSansPro-Regular;" class="">and:</div><div style="font-family: SourceSansPro-Regular;" class=""><br class=""></div><div class=""><span style="font-family: SourceSansPro-Regular;" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let Dog = Python</span><font face="SourceSansPro-Regular" class="">.import(“DogModule.Dog")</font></div><div style="font-family: SourceSansPro-Regular;" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let dog = Dog("Briana")</div><div style="font-family: SourceSansPro-Regular;" class=""><br class=""></div><div style="font-family: SourceSansPro-Regular;" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>dog.add_trick("snore")</div><div style="font-family: SourceSansPro-Regular;" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>//&nbsp;becomes:</div><div style="font-family: SourceSansPro-Regular;" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>dog[keyPath:&nbsp;\PyVal.add_trick]("snore")</div><div style="font-family: SourceSansPro-Regular;" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>//&nbsp;or fully expanded:</div><div style="font-family: SourceSansPro-Regular;" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>dog[keyPath:&nbsp;PyVal.supplementalKeypath(for: "add_trick")]("snore")</div><div style="font-family: SourceSansPro-Regular;" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>// calls dog[dynamicMember: name]</div><div class=""><br class=""></div><div class="">You now have one more level of indirection which allows key paths. There's no compile time checking however: all imaginable key paths will work.</div><div><br class=""><blockquote type="cite" class=""><div class="">Le 16 nov. 2017 à 1:00, Brent Royal-Gordon via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; a écrit :</div></blockquote><blockquote type="cite" class=""><br class=""></blockquote><blockquote type="cite" class=""><div class=""><div class="" style="font-family: SourceSansPro-Regular; font-size: 15px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;">* Actually, for that matter, let's talk about key paths. In principle, you can already think of member lookup in Swift—or at least property and subscript lookup—as though it always worked by constructing a key path and using `subscript(keyPath:)` to access it. Is there some way we could model this feature as extending the set of keys available on a given type—perhaps in a way that allowed compile-time-limited and strongly-typed sets of keys, like I mention with the `UIAppearance` example, in addition to the open-ended, type-erased sets you need—and then looking things up by key path? (Sorry if this is a little vague—I know very little about how key paths are implemented.)</div><br class="Apple-interchange-newline"></div></blockquote></div></div><br class=""><div class="">
<div style="color: rgb(0, 0, 0); letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="color: rgb(0, 0, 0); letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="color: rgb(0, 0, 0); letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="color: rgb(0, 0, 0); font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; border-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-stroke-width: 0px;"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; border-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-stroke-width: 0px;"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; border-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-stroke-width: 0px;"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">--&nbsp;<br class="">Michel Fortin</div><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><span style="text-align: -webkit-auto;" class=""><a href="https://michelf.ca" class="">https://michelf.ca</a></span></div></span></div></span></div></span></div></div></div></div>
</div>
<br class=""></body></html>