I love the proposal and it is great to see this feature being considered. This
provides a great foundation for future functionality. I too find the syntax
confusing. The syntax is elegant and does not introduce any extra keywords, but
accessing key paths is an advanced “meta” feature and does not have to be this
straightforward. I would prefer less potential ambiguity at the expense of a
little extra verbosity.
I suggest that the all keypaths be grouped under a `keypaths` pseudo-root path.
This eliminates potential ambiguity with other language constructs and is
easier for humans ( and as an added benefit, the compiler) to parse, reducing
potential errors and clearer error diagnostics for name collisions and
misspellings. Compiler reasoning and error messages are difficult enough deal
with today. The use of a unique root for all keypaths will also greatly
simplify searching for uses and code maintenance.
Many of the advanced language features that have been proposed for Swift add
elegance and power to the language, but they have a cost in comprehensibility
especially to beginners. The use of `keypaths` greatly improves the
discoverability of this feature.
Another potential benefit of introducing a keyword-like construct now could
simplifies the task of adding more metadata with other pseudo-root paths like
`classKeypaths` and others as the language evolves.
Here is your example, rewritten with `keypaths` highlighted as a keyword. It
does not add any additional nesting or operators, but clearly identifies the
construct as something different and provides a simple term to search for in
documentation.
struct Person {
var name: String
var friends: [Person]
var bestFriend: Person?
}
var han = Person(name: "Han Solo", friends: [])
var luke = Person(name: "Luke Skywalker", friends: [han])
let firstFriendsNameKeyPath = Person.keypaths.friends[0].name
let firstFriend = luke[keypaths.path] // han
// or equivalently, with type inferred from context
let firstFriendName = luke[keypaths.friends[0].name]
// rename Luke's first friend
luke[firstFriendsNameKeyPath] = "A Disreputable Smuggler"
let bestFriendsName = luke[keypaths.bestFriend]?.name // nil, if he is the
last jedi
> On Mar 17, 2017, at 12:27 PM, Vladimir.S via swift-evolution
> <[email protected]> wrote:
>
> On 17.03.2017 20:04, Michael LeHew via swift-evolution wrote:
>> Hi friendly swift-evolution folks,
>>
>> The Foundation and Swift team would like for you to consider the following
>> proposal:
>>
>> Many thanks,
>> -Michael
>>
>>
>> Smart KeyPaths: Better Key-Value Coding for Swift
>> ...
>
> Just my 2 cents. FWIW, I feel like the proposed syntax is VERY confusing.
>
> Person.friends[0].name - like access to static property. T.method can't have
> subscript for it and then some field. So, I believe such key paths deserve
> its own syntax.
>
> luke[path] - very close to access the subscript of instance. In compare to
> T.method, we can call result of T.method(i.e. let m = T.method; m()), just
> like the T.method itself(foo.method()). But here we are calling some kind of
> subscript instead of access property by "path".
>
> There is no some 'special' marker for me that saying "hey, there is
> references to properties used" from the first look.
>
> Probably we can consider another separators, like
>
> Person:friends[0].name
> luke:path
>
> Person->friends[0].name
> luke->path
>
> Person[friends[0].name] // single brackets for type
> luke[[path]] // double brackets for instance
>
> Person@friends[0].name
> luke@path
>
> or other with help of community.
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution