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