[swift-evolution] Smart KeyPaths

David Hart david at hartbit.com
Thu Mar 30 05:22:24 CDT 2017



> On 30 Mar 2017, at 09:41, Douglas Gregor <dgregor at apple.com> wrote:
> 
> 
> 
> Sent from my iPhone
> 
>> On Mar 29, 2017, at 10:35 PM, David Hart <david at hartbit.com> wrote:
>> 
>> 
>> 
>> 
>> 
>> Sent from my iPhone
>> On 30 Mar 2017, at 01:13, Michael J LeHew Jr via swift-evolution <swift-evolution at swift.org> wrote:
>> 
>>> Thanks for the feedback everyone!  We have pushed a changed a bit ago to the proposal reflecting these desires.
>>> 
>>> https://github.com/apple/swift-evolution/pull/644/files
>>> 
>>> -Michael
>> 
>> I'm not a fan of the new syntax for creating key paths. To me, it feels like they've been demoted to second class citizens of the language simply because of how more verbose it now is. The new syntax is also too confusingly similar to string key paths: I had to look closely at the code to see the difference. Is there no symbol we can use to make it ambiguous? Ideas:
>> 
>> Person::friend.lastName
>> Person/friend.lastName
>> Person#friend.lastName
>> 
>> I'm a fan of the first one as it has similarities to names pacing in C++.
> 
> We might want to reserve :: for actual scope resolution. At least, we need something to be able to disambiguate when the same name occurs as a member in (e.g.) multiple protocols, and :: is familiar-ish. 

Perhaps, but I still believe we would gain a lot by keeping a similar syntax, whatever the separation token.

> I'm surprised nobody brought up making
> 
>   #keyPath(Person.friend.lastName)
> 
> Work as either a String or KeyPath. Probably a bad idea. 

If it works, would be better than the current version of the proposal IMHO, buts it's still fairly verbose for a feature that can become a first class citizen of the language. #keyPath was fine because it was an obscure objc bridging feature.

>  - Doug
> 
>> 
>> David.
>> 
>>>>> On Mar 29, 2017, at 2:49 PM, Douglas Gregor <dgregor at apple.com> wrote:
>>>>> 
>>>>> 
>>>>> On Mar 17, 2017, at 10:04 AM, Michael LeHew via swift-evolution <swift-evolution at swift.org> wrote:
>>>>> 
>>>>> Hi friendly swift-evolution folks,
>>>>> 
>>>>> The Foundation and Swift team  would like for you to consider the following proposal:
>>>> 
>>>> 
>>>> The Swift core team discussed this proposal draft and had a little bit of pre-review feedback.
>>>> 
>>>>> Access and Mutation Through KeyPaths
>>>>> To get or set values for a given root and key path we effectively add the following subscripts to all Swift types. 
>>>>> 
>>>>> Swift
>>>>> extension Any {
>>>>>     subscript(path: AnyKeyPath) -> Any? { get }
>>>>>     subscript<Root: Self>(path: PartialKeyPath<Root>) -> Any { get }
>>>>>     subscript<Root: Self, Value>(path: KeyPath<Root, Value>) -> Value { get }
>>>>>     subscript<Root: Self, Value>(path: WritableKeyPath<Root, Value>) -> Value { set, get }
>>>>> }
>>>> 
>>>> Swift doesn’t currently have the ability to extend Any, so this is (currently) pseudocode for compiler magic that one day we might be able to place. Additionally, the “Root: Self” constraint isn’t something we support in the generics system. A small note indicating that this is pseudo-code meant to get the point across (rather than real code to drop into the standard library/Foundation) would be appreciated.
>>>> 
>>>> More importantly, this adds an unlabeled subscript to every type, which raises concerns about introducing ambiguities—even if not hard ambiguities that prevent code from compiling (e.g., from a Dictionary<AnyKeyPath, …>)---they can still show up in code completion, diagnostics, etc.
>>>> 
>>>> The core team would prefer that this subscript distinguish itself more, e.g., by labeling the first parameter “keyPath” (or some better name, if there is one). Syntactically, that would look like:
>>>> 
>>>> 	person[keyPath: theKeyPathIHave]
>>>> 
>>>>> Referencing Key Paths
>>>>> 
>>>>> Forming a KeyPath borrows from the same syntax used to reference methods and initializers,Type.instanceMethod only now working for properties and collections. 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.
>>>>> 
>>>> The core team was concerned about the use of the Type.instanceProperty syntax for a few reasons:
>>>> 
>>>> 	* It doesn’t work for forming keypaths to class/static properties (or is ambiguous with the existing meaning(, so we would need another syntax to deal with that case
>>>> 	* It’s quite subtle, even more so that the existing Type.instanceMethod syntax for currying instance methods
>>>> 
>>>>> There is no change or interaction with the #keyPath() syntax introduced in Swift 3. 
>>>>> 
>>>> The core team felt that extending the #keyPath syntax was a better syntactic direction to produce key-paths.
>>>> 
>>>> 	- Doug
>>>> 
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170330/fc7e865f/attachment.html>


More information about the swift-evolution mailing list