[swift-evolution] [Pitch #2] Introduce User-defined "Dynamic Member Lookup" Types

Chris Lattner clattner at nondot.org
Wed Nov 29 09:19:36 CST 2017


> On Nov 29, 2017, at 2:21 AM, Jonathan Hull <jhull at gbis.com> wrote:
> 
> I noticed all of the examples return the same type as they are defined on (JSON has a subscript that returns JSON).  Is there an example of where this is not the case?

Yes, they exist, there is one in the Python interop layer that I’m working on: it is a separate type that vends all the Python builtins.  It returns them as PyVal's.

-Chris



> 
> 
>> On Nov 25, 2017, at 3:16 PM, Chris Lattner via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> 
>> On Nov 20, 2017, at 10:36 PM, Chris Lattner <clattner at nondot.org <mailto:clattner at nondot.org>> wrote:
>>> Hi all,
>>> 
>>> I’ve significantly revised the ‘dynamic member lookup’ pitch, here’s the second edition:
>>> https://gist.github.com/lattner/b016e1cf86c43732c8d82f90e5ae5438 <https://gist.github.com/lattner/b016e1cf86c43732c8d82f90e5ae5438>
>>> 
>>> I’ve incorporated some minor changes to it:
>>> - I’ve made it possible to provide read-only dynamic members.
>>> - I’ve added an example JSON use-case which uses read-only dynamic members.
>>> - Minor wording changes.
>> 
>> 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:
>> 
>> /// Types type conform to this protocol have the behavior that member lookup -
>> /// accessing `someval.member` will always succeed.  Failures to find normally
>> /// declared members of `member` will be turned into subscript references using
>> /// the `someval[dynamicMember: member]` member.
>> ///
>> public protocol DynamicMemberLookupProtocol {
>>   // Implementations of this protocol must have a subscript(dynamicMember:)
>>   // implementation where the keyword type is some type that is
>>   // ExpressibleByStringLiteral.  It can be get-only or get/set which defines
>>   // the mutability of the resultant dynamic properties.
>>   
>>   // subscript<KeywordType: ExpressibleByStringLiteral, LookupValue>
>>   //  (dynamicMember name: KeywordType) -> LookupValue { get }
>> }
>> 
>> 
>> A design like this can almost work:
>> 
>> public protocol DynamicMemberLookupProtocol {
>>   associatedtype DynamicMemberLookupKeyword : ExpressibleByStringLiteral
>>   associatedtype DynamicMemberLookupValue
>>   
>>   subscript(dynamicMember name: DynamicMemberLookupKeyword)
>>     -> DynamicMemberLookupValue { get }
>> }
>> 
>> The problem is that now everything that conforms to DynamicMemberLookupProtocol is a PAT, so it doesn’t work with existentials.  We could almost make due with a generic subscript:
>> 
>> public protocol DynamicMemberLookupProtocol {
>>   subscript<KeywordType: ExpressibleByStringLiteral, LookupValue>
>>     (dynamicMember name: KeywordType) -> LookupValue { get }
>> }
>> 
>> but it turns out that while you can declare that, nothing can actually conform to it with concrete types (I filed SR-6473, but it isn’t clear that it ever can work given how our generics system works).
>> 
>> Defining this as an empty marker protocol has several advantages:
>>  - Only one protocol is required
>>  - Suddenly you can define mutating getters and nonmutating setters
>>  - Existentials work as well as concrete types.
>> 
>> -Chris
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20171129/352e07d5/attachment.html>


More information about the swift-evolution mailing list