[swift-evolution] Proposal: Introduce User-defined "Dynamic Member Lookup" Types

Chris Lattner clattner at nondot.org
Mon Nov 27 15:24:50 CST 2017

> On Nov 27, 2017, at 12:54 PM, Dave DeLong <swift at davedelong.com> wrote:
> Hi Chris,
> Some questions:
> 1️⃣ How does the subscript approach work for dynamically passing in multiple parameters? For example, what would “dog.addTrick(“Roll Over”, favorite: true)” be when expressed as a subscript method? The subscript syntax only really seems to suit property-style invocations, unless I’m missing something obvious.
> 2️⃣ It seems like “dog.add_trick(…)” would have a dynamic lookup name of “add_trick”. What would the lookup name of “dog.add(trick: …)” be? Or in other words, how do named parameters affect the lookup name?

Hi Dave,

Both of these questions are really about the other proposal, the DynamicCallable proposal:
https://gist.github.com/lattner/a6257f425f55fe39fd6ac7a2354d693d <https://gist.github.com/lattner/a6257f425f55fe39fd6ac7a2354d693d>

It isn’t as refined as the DynamicMemberLookup proposal, but the two do work together.

DynamicMemberLookup is only about changing how “x.y” resolves.

> 3️⃣ Can I implement the subscript method multiple times, or is only a single implementation allowed?

Multiple implementations are allowed and are resolved through standard overload resolution. Here’s an extract from the test case in the patch:

// References to overloads are resolved just like normal subscript lookup:
+// they are either contextually disambiguated or are invalid.
+struct Ambiguity : DynamicMemberLookupProtocol {
+  subscript(dynamicMember member: String) -> Int {
+    return 42
+  }
+  subscript(dynamicMember member: String) -> Float {
+    return 42
+  }
+func testAmbiguity(a : Ambiguity) {
+  let _ : Int = a.flexibility
+  let _ : Float = a.dynamism
+  _ = a.dynamism  // expected-error {{ambiguous use of 'subscript(dynamicMember:)'}}

> For example, in the JSON example, there’s currently only a dynamic member subscript implementation that returns “JSON?”. Could I add another one that returns “String?” and have the type checker choose the appropriate one based on type inference?

Yes.  It is tricky to actually use such APIs, but they are definitely possible and work exactly like current overloads in Swift do.

> As far as naming goes, I’d propose “DynamicMemberForwarding”. In my mind, “Lookup” and “Resolve” are inappropriate, because you’re not actually “looking up” or “resolving” to a particular implementation. In Objective-C, the “+resolveInstanceMethod” stuff expects you to *provide* a method implementation (an IMP). On the other hand, if there isn’t a method implementation (which is the case here), you end up in the “-forwardInvocation:” path, where you can just introspect the NSInvocation and do whatever it is you’re doing to do. So, it seems like this proposal sounds a lot more like ObjC's “invocation forwarding” rather than the method resolution; hence my preference for using “Forwarding” in the name for naming consistency.

Sure, I’m not strongly attached to any of the names in the proposal.


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

More information about the swift-evolution mailing list