And all APIs with string types which were actually key paths would have to be modified to use it. Then `-(nullable id)valueForKeyPath:(NSKeyPath)keyPath` would import as `func value(for: NSKeyPath) -> AnyObject?`. This proposal's `#keyPath` construct would have to then construct an `NSKeyPath` instead of a `String`.
(To make this all work, it might make sense to add a KeyPathLiteralConvertible protocol to the standard library. As a bonus, if this protocol's initializer received enough metadata, it might be able to construct alternate forms of key paths, such as the Rails-style ones which handle arrays somewhat differently from Foundation's.)
This is more work, but it's also more general, which is a pretty cool prospect!
If key paths were some stronger type (as Brent is suggesting), we could do this. However, because key paths are just Strings, we need to compensate for weak type information <Swift.org - API Design Guidelines, so valueForKeyPath should retain it’s currently name despite the redundancy in many use sites with keypath.
- Doug
···
On Apr 7, 2016, at 9:34 PM, Les Pruszynski via swift-evolution <swift-evolution@swift.org> wrote:
This is my first post on this list so please bear with me.
I very much like this proposal but what bothers me is this doubling of valueForKeyPath(keypath(xxx) in the signature of the function.
Key-Paths do support operators and custom functions. How should this work
within the context of this proposal?
···
2016-04-12 11:14 GMT+02:00 Brent Royal-Gordon via swift-evolution < swift-evolution@swift.org>:
> I very much like this proposal but what bothers me is this doubling of
valueForKeyPath(keypath(xxx) in the signature of the function.
>
> chris.valueForKeyPath(keypath(Person.bestFriend.lastName)) // => Groff
>
> chris
> .valueForKeyPath(keypath(Person.friends.firstName)) // => ["Joe",
"Douglas"]
>
> I’m not sure whether the form below is actually possible. For me it
reads more naturally and is more consistent with “Modern Swift” as far as I
know.
>
> chris.valueFor(keypath(Person.friends.firstName)) // => ["Joe",
"Douglas”]
> or maybe
> chris.valueOf(keypath(Person.friends.firstName)) // => ["Joe",
"Douglas”]
And all APIs with string types which were actually key paths would have to
be modified to use it. Then `-(nullable
id)valueForKeyPath:(NSKeyPath)keyPath` would import as `func value(for:
NSKeyPath) -> AnyObject?`. This proposal's `#keyPath` construct would have
to then construct an `NSKeyPath` instead of a `String`.
(To make this all work, it might make sense to add a
KeyPathLiteralConvertible protocol to the standard library. As a bonus, if
this protocol's initializer received enough metadata, it might be able to
construct alternate forms of key paths, such as the Rails-style ones which
handle arrays somewhat differently from Foundation's.)
This is more work, but it's also more general, which is a pretty cool
prospect!
*REWE Digital GmbH*
Domstraße 20, 50668 Köln, Büro: Schanzenstr. 6-20, 51063 Köln
Geschäftsführer: Dr. Jean-Jacques Michel van Oosten (Vorsitzender),
Christoph Eltze, Dr. Johannes Steegmann, Dr. Robert Zores
Handelsregister: Amtsgericht Köln (HRB 78670) UST-ID-Nr.: DE 290 605 450
Aeons ago, I was on the team that invented key paths. There were some pretty major performance issues:
- the key path had to be separated into its individual components, requiring processing time and generating a bunch of garbage
- the obvious thing to do would have been to parse the key path into an array of strings up front, and then simply process the key path in a loop, but this was not possible because some objects might override valueForKeyPath and be expecting to parse their own portion of the key path (and down) in some special way
- pre-parsing may also be problematic because key paths could contain operators like @count, or @sum, @avg, etc.
That being said, it would certainly be nice if the compiler pre-parsed key paths into either:
- key path objects
- arrays of strings
- arrays of “key” objects
and KVC was modified to accept these as a lower level API.
Perhaps it would be prudent to pull in the Foundation guys on this and get their input before implementing something on the Swift side that would be hard to take back.
-Kenny
···
On Apr 12, 2016, at 9:35 AM, Douglas Gregor via swift-evolution <swift-evolution@swift.org> wrote:
On Apr 7, 2016, at 9:34 PM, Les Pruszynski via swift-evolution <swift-evolution@swift.org> wrote:
This is my first post on this list so please bear with me.
I very much like this proposal but what bothers me is this doubling of valueForKeyPath(keypath(xxx) in the signature of the function.
If key paths were some stronger type (as Brent is suggesting), we could do this. However, because key paths are just Strings, we need to compensate for weak type information, so valueForKeyPath should retain it’s currently name despite the redundancy in many use sites with keypath.