Why can’t key paths refer to instance methods?

I’m not so sure. If we introduce syntax for unbound method key paths it might be possible to allow them to be used in contexts SE-0042 would have supported:

func takesMutating(_: (inout Foo) -> Void {}
func takesMutatingWithArg(_: (inout Foo, Int) -> Void) {}

struct Foo {
   mutating func bar() { }
   mutating func baz(_: Int) { }
}

takesMutating(\Foo.bar)
takesMutatingWithArg(\Foo.baz)

// possibly even this:
takesMutating(\.bar)
takesMutatingWithArg(\.baz)

What about the above approach seems thorny? IIRC, @Joe_Groff has mentioned method key paths in the context of a path forward for SE-0042 in the past. Perhaps something like this is what he had in mind.

In any case, I think it’s really important that we think about this before pushing forward with a method key path proposal. Even if mutating methods are not supported now, I’d like to know how they fit in as a future direction. It would be a shame to design ourselves into a corner where they are difficult to add later. And it would also be a shame to need an entirely different mechanism in addition to the existing unbound methods and the proposed method key paths.

The first example there looks very straightforward if you use subscript key paths as a precedent.

The second example with partially supplied arguments is not as straightforward because it requires syntax for the “hole” and is less clear how it might correspond to the key path type. I think this would be interesting to explore but is less important and should probably be left as a future enhancement.

I’m a bit out of my league here, but that looks closer to higher-rank types than existentials to me. I’ve never seen higher-rank types discussed outside the context of function types before though so I’m not sure.

1 Like