[swift-evolution] [Pitch #2] Introduce User-defined "Dynamic Member Lookup" Types
Jonathan Hull
jhull at gbis.com
Wed Nov 29 04:21:27 CST 2017
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?
> On Nov 25, 2017, at 3:16 PM, Chris Lattner via swift-evolution <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
> 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/b5f93135/attachment.html>
More information about the swift-evolution
mailing list