<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="">On Nov 20, 2017, at 10:36 PM, Chris Lattner &lt;<a href="mailto:clattner@nondot.org" class="">clattner@nondot.org</a>&gt; wrote:<div><blockquote type="cite" class=""><div class=""><div class="">Hi all,<br class=""><br class="">I’ve significantly revised the ‘dynamic member lookup’ pitch, here’s the second edition:<br class=""><a href="https://gist.github.com/lattner/b016e1cf86c43732c8d82f90e5ae5438" class="">https://gist.github.com/lattner/b016e1cf86c43732c8d82f90e5ae5438</a><br class=""><br class="">I’ve incorporated some minor changes to it:<br class="">- I’ve made it possible to provide read-only dynamic members.<br class="">- I’ve added an example JSON use-case which uses read-only dynamic members.<br class="">- Minor wording changes.<br class=""></div></div></blockquote></div><br class=""><div class="">Just to talk to myself a bit here, but I’ve come to realize that the right design really is to have a simple empty marker protocol like this:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0); background-color: rgb(255, 255, 255);" class="">/// Types type conform to this protocol have the behavior that member lookup -</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0); background-color: rgb(255, 255, 255);" class="">/// accessing `someval.member` will always succeed.&nbsp; Failures to find normally</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0); background-color: rgb(255, 255, 255);" class="">/// declared members of `member` will be turned into subscript references using</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0); background-color: rgb(255, 255, 255);" class="">/// the `someval[dynamicMember: member]` member.</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0); background-color: rgb(255, 255, 255);" class="">///</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="color: #ba2da2" class="">public</span> <span style="color: #ba2da2" class="">protocol</span> DynamicMemberLookupProtocol {</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0); background-color: rgb(255, 255, 255);" class=""><span style="color: #000000" class="">&nbsp; </span>// Implementations of this protocol must have a subscript(dynamicMember:)</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0); background-color: rgb(255, 255, 255);" class=""><span style="color: #000000" class="">&nbsp; </span>// implementation where the keyword type is some type that is</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0); background-color: rgb(255, 255, 255);" class=""><span style="color: #000000" class="">&nbsp; </span>// ExpressibleByStringLiteral.&nbsp; It can be get-only or get/set which defines</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0); background-color: rgb(255, 255, 255);" class=""><span style="color: #000000" class="">&nbsp; </span>// the mutability of the resultant dynamic properties.</div><p style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255); min-height: 13px;" class="">&nbsp;&nbsp;<br class="webkit-block-placeholder"></p><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0); background-color: rgb(255, 255, 255);" class=""><span style="color: #000000" class="">&nbsp; </span>// subscript&lt;KeywordType: ExpressibleByStringLiteral, LookupValue&gt;</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0); background-color: rgb(255, 255, 255);" class=""><span style="color: #000000" class="">&nbsp; </span>//&nbsp; (dynamicMember name: KeywordType) -&gt; LookupValue { get }</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">}</div></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">A design like this can almost work:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="color: #ba2da2" class="">public</span> <span style="color: #ba2da2" class="">protocol</span> DynamicMemberLookupProtocol {</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; <span style="color: #ba2da2" class="">associatedtype</span> DynamicMemberLookupKeyword : <span style="color: #703daa" class="">ExpressibleByStringLiteral</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; <span style="color: #ba2da2" class="">associatedtype</span> DynamicMemberLookupValue</div><p style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255); min-height: 13px;" class="">&nbsp;&nbsp;<br class="webkit-block-placeholder"></p><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170); background-color: rgb(255, 255, 255);" class=""><span style="color: #000000" class="">&nbsp; </span><span style="color: #ba2da2" class="">subscript</span><span style="color: #000000" class="">(dynamicMember name: </span>DynamicMemberLookupKeyword<span style="color: #000000" class="">)</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170); background-color: rgb(255, 255, 255);" class=""><span style="color: #000000" class="">&nbsp; &nbsp; -&gt; </span>DynamicMemberLookupValue<span style="color: #000000" class=""> { </span><span style="color: #ba2da2" class="">get</span><span style="color: #000000" class=""> }</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0); background-color: rgb(255, 255, 255);" class=""><div style="color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px;" class=""><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div><div class=""><br class=""></div></div></div></div><div class="">The problem is that now everything that conforms to&nbsp;DynamicMemberLookupProtocol is a PAT, so it doesn’t work with existentials. &nbsp;We could almost make due with a generic subscript:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="color: rgb(186, 45, 162);" class="">public</span>&nbsp;<span style="color: rgb(186, 45, 162);" class="">protocol</span>&nbsp;DynamicMemberLookupProtocol {</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp;&nbsp;<span style="color: #ba2da2" class="">subscript</span>&lt;KeywordType: ExpressibleByStringLiteral, LookupValue&gt;</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; (dynamicMember name: <span style="color: #703daa" class="">KeywordType</span>) -&gt; <span style="color: #703daa" class="">LookupValue</span> { <span style="color: #ba2da2" class="">get</span> }</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">}</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0); background-color: rgb(255, 255, 255);" class=""><div style="color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px;" class=""><div class=""><br class=""></div><div class="">but it turns out that while you can declare that, nothing can actually conform to it with concrete types (I filed&nbsp;SR-6473, but it isn’t clear that it ever can work given how our generics system works).</div><div class=""><br class=""></div><div class="">Defining this as an empty marker protocol has several advantages:</div><div class="">&nbsp;- Only one protocol is required</div><div class="">&nbsp;- Suddenly you can define mutating getters and nonmutating setters</div><div class="">&nbsp;- Existentials work as well as concrete types.</div><div class=""><br class=""></div><div class="">-Chris</div><div class=""><br class=""></div></div></div></div></body></html>