On Nov 20, 2017, at 10:36 PM, Chris Lattner <clatt...@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 > > 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@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution