> On Mar 29, 2017, at 7:00 PM, James Berry <jbe...@rogueorbit.com> wrote:
> 
>> 
>> On Mar 29, 2017, at 5:37 PM, Joe Groff <jgr...@apple.com> wrote:
>> 
>> 
>>> On Mar 29, 2017, at 5:26 PM, Michael J LeHew Jr via swift-evolution 
>>> <swift-evolution@swift.org> wrote:
>>> 
>>> 
>>>> On Mar 29, 2017, at 5:12 PM, James Berry <jbe...@rogueorbit.com> wrote:
>>>> 
>>>>> Referencing Key Paths
>>>>> 
>>>>> Forming a KeyPath borrows from the same syntax added in Swift 3 to 
>>>>> confirm the existence of a given key path, only now producing concrete 
>>>>> values instead of Strings. Optionals are handled via optional-chaining. 
>>>>> Multiply dotted expressions are allowed as well, and work just as if they 
>>>>> were composed via the appending methods on KeyPath.
>>>>> 
>>>>> There is no change or interaction with the #keyPath() syntax introduced 
>>>>> in Swift 3. #keyPath(Person.bestFriend.name) will still produce a String, 
>>>>> whereas #keyPath(Person, .bestFriend.name) will produce a KeyPath<Person, 
>>>>> String>.
>>>> 
>>>> This distinction seems arbitrary and confusing. The user is supposed tor 
>>>> remember that the #keyPath(Person.bestFriend.name) form produces a string 
>>>> while the #keyPath(Person, .bestFriend.name) form produces a key path 
>>>> object? I don’t think we’re advancing here. What would be the effect if 
>>>> just the former was valid, and (always/now) produced a keypath object that 
>>>> was convertible to string? How bad would the breakage be?
>>> 
>>> The syntax subtleties here are unfortunate. 
>>> 
>>> An idea that we discussed was to be able to tell when a #keyPath wants to 
>>> be considered as a string and either implicitly or having some affordance 
>>> for doing so. Back then this was harder because we had #keyPaths that could 
>>> not be represented as a string (an earlier draft had keyPaths that could 
>>> compose with closures; which while powerful, weren't really key paths any 
>>> more. That idea was removed from the proposal we shared as they are 
>>> intrinsically opposed to being able to serializing/deserialize key paths).  
>>> 
>>> Given that we don't support those kinds of key paths, nor are we really 
>>> considering adding them back thanks to our desire to support serializing 
>>> key paths to file in the future, this is a very reasonable idea I think. 
>> 
>> One small problem with the Swift 3 key path syntax when generalized to allow 
>> arbitrary Swift types at the root, and to also allow inference of the root, 
>> is that [...] can be either a subscript or an Array type reference, so it 
>> wouldn't be clear whether #keyPath([a].foo) is the path `.foo` rooted on the 
>> type `[a]` or the path `[a].foo` rooted in the contextual root type. We 
>> could say that you have to use a different syntax for a contextual keypath 
>> that begins with a subscript, like `#keyPath(.self[a])` or `#keyPath(.[a])`, 
>> perhaps.
> 
> To me it seems an acceptable compromise to require a leading dot for the 
> contextual case:
> 
>       #keyPath(Person.bestFriend.name)
>       #keyPath(.bestFriend.name)
>       #keyPath(.[a])

Another problem with overloading the same syntax is that ObjC key path checking 
has a bunch of special case logic to mimic Cocoa's KVC behavior, so that key 
paths involving string NSDictionary keys, NSArray's implicit mapping behavior, 
or untyped keys accessed through `id` work as one would expect in ObjC. We 
would only want to do that checking for ObjC key paths, so we should probably 
keep them syntactically distinct.

-Joe
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to