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

Chris Lattner clattner at nondot.org
Wed Nov 29 09:25:10 CST 2017

> On Nov 29, 2017, at 12:46 AM, Brent Royal-Gordon <brent at architechies.com> wrote:
>> On Nov 28, 2017, at 8:35 PM, Chris Lattner <clattner at nondot.org> wrote:
>> We’ve had a lot of discussions over the years about how to balance simplicity vs power, implicitness vs explicitness, intentionality vs accidental behavior, etc.  For example, in very early discussions about Swift generics, some folks where strong proponents of protocol conformance being fully implicit: satisfying all the requirements of a protocol meant that you conformed to it, even if you didn’t explicitly “inherit” from it.
>> This is obviously not the design we went with over the long term, and I’m glad we didn’t.
> I get that, but an attribute in particular would be just as explicit as a protocol conformance.

Sure, I’m not attached to spelling.  I think that conformance is the right way to do this (following the pattern of the other ExpressibleBy etc types), but if you have a compelling argument for some specific spelling, I’m more than happy to discuss it.

>> I think that DynamicMemberLookup requiring conformance is the same thing: it makes it explicit that the behavior is intentional, and it allows somewhat better error checking (if you conform to the protocol but don’t implement the (implicitly known) requirement, you DO get an error).  That said, this is just my opinion.  
> So you envision that the compiler knows that `DynamicMemberLookupProtocol`-conforming types ought to have `subscript(dynamicMember:)` members, and these members ought to have certain traits (unary, ExpressibleByStringLiteral parameter, etc.), and it should enforce those traits, even though there's no matching requirement in the protocol?

Yes, this is implemented in the patch, it is a straight-forward additional check in protocol conformance.

Keep in mind that the compiler has other similar things for features that are not expressible in the Swift type system, e.g. the type(of:) function.

> That seems like a lot of compiler magic to attach to a particular protocol. A `@dynamicMember` attribute would have a similar amount of magic, but people *expect* that kind of magic from an attribute. For instance, the `@objc` attribute places lots of conditions on the types of parameters, etc., and nobody is surprised by that.

I don’t really think that’s the case.  Attributes have their place, for sure, but there in high precedent for Protocols providing exposing language features to types.

> Other reasons to prefer an attribute:
> * I can't think of a use case where you would want dynamic members but not want to make the subscript itself accessible. If `@dynamicMember` could be applied to any subscript, then you could use any label (or no label) for sugar-free use of the dynamic functionality. For instance, the JSON example could decorate its existing subscript instead of introducing a redundant one:

I see the small advantage, but isn’t precedented at all.  The ExpressibleBy protocols require redeclaring redundant methods just like this.

> * If we eventually want to support multiple subscripts with different types (either by using different return types, 

This is already supported in the patch, and the patch includes a test case.

> Basically, you're using a hammer to drive a screw. Why not use a screwdriver instead?

I don’t see a connection between this rhetorical mechanic and the topic at hand :-)


More information about the swift-evolution mailing list