[swift-evolution] Smart KeyPaths

Michael LeHew lehewjr at apple.com
Fri Mar 17 18:36:38 CDT 2017


> On Mar 17, 2017, at 3:57 PM, Joe Groff <jgroff at apple.com> wrote:
> 
>> 
>> On Mar 17, 2017, at 1:58 PM, Brent Royal-Gordon via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> 
>>> On Mar 17, 2017, at 10:04 AM, Michael LeHew via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>> Introduction
>>> We propose a family of concrete Key Path types that represent uninvoked references to properties that can be composed to form paths through many values and directly get/set their underlying values.
>>> 
>> I don't know how to express the level of "Yes" I feel in response to this proposal without using language that's inappropriate on a public mailing list.
>> 
>> A few questions:
>> 
>> How do key paths interact with Optionals? Can you form a key path to `Person.bestFriend.name`, and is that the syntax, or is it `Person.bestFriend?.name`?
>> 
>> Foundation key paths have a sometimes-useful property where, if they traverse a collection, the result becomes a collection of the ending type. Is a similar feature planned for smart key paths—perhaps something like `Person.friends[].name`?
> 
> In many cases, you could add a property or subscript operation that has the same effect, e.g.:
> 
> extension Array {
>   subscript<NewElement>(mapping key: KeyPath<Element, NewElement>) -> Array<NewElement> {
>     return map { $0[key] }
>   }
> }

A non-trivial benefit that's easy to overlook with this kind of approach (vs more ad-hoc closure transformed KeyPaths) is that the contract and capabilities are part of the API surface of your type and thus more easily testable.


> 
> would let you write `Person.friends[mapping: .name]`. Before publishing the proposal, we had discussed having closure-based key path components. However, as Michael noted, an important capability of key paths in ObjC is that, while abstractly they're "just functions" in a sense, they're also introspectable and serializable values. Closures in Swift are by design opaque, so can't be equated, hashed, traversed by component, or serialized. Keeping key paths attached to declarations lets them preserve that structure, enabling their use for more interesting things like KVO in the future.
> 
> -Joe
> 
>> Given that Swift has a syntax called #keyPath which is unrelated to these "key paths", have you considered using a different name to avoid confusion? Maybe "property paths" or "accessor paths"?
>> 
>> -- 
>> Brent Royal-Gordon
>> Architechies
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170317/34c98de2/attachment.html>


More information about the swift-evolution mailing list