[swift-evolution] [Draft] Obejctive-C Keypaths

David Hart david at hartbit.com
Tue Mar 8 01:21:53 CST 2016

> If we went this route, I would suggest changing a few things here.
> 1. #keypath should be equivalent to a string literal, not necessarily a `Swift.String`. That would allow you to store it into StaticString or other StringLiteralConvertible types. (If you had an enum corresponding to the available properties, you might even be able to conform it to StringLiteralConvertible and use this feature with it.)

Sounds good to me!

> 2. We *may* want to consider calling it something that's slightly less tied to Cocoa terminology, like #name or #property. (#key might be a good compromise between the two.) I don't think this is *necessary*, but we might want to consider it.

I don’t think this is a good idea because:
- #name, #property, #key all hide the ability to chain properties for a “key path”.
- #keypath already has prior meaning to so many developers.

Even if #keypath exists without the Objective-C runtime, I think that the name is strong enough meaning to keep it’s weight. What do you think?

> 3. It would be nice if you could easily get a name for a property on `self`, and it might even make sense to allow you to easily get a name for a property on any variable. Maybe the syntax (assuming that this code is inside a `Person`) would be more like:
> 	print(#key(Person.bestFriend.firstName))		// => bestFriend.firstName
> 	print(#key(chris.bestFriend.firstName))			// => bestFriend.firstName
> 	print(#key(bestFriend.firstName)				// => bestFriend.firstName
> Note that that last form has a slightly tricky rule: because the only visible `bestFriend` is a property, `#name(bestFriend.firstName)` is actually `#name(self.bestFriend.firstName)`, so the `self` is what's stripped off. A small redesign would disambiguate:
> 	print(Person.#key(bestFriend.firstName))		// => bestFriend.firstName
> 	print(chris.#key(bestFriend.firstName))			// => bestFriend.firstName
> 	print(#key(bestFriend.firstName)				// => bestFriend.firstName

I understand the reasoning behind this modification, I would also like to be able to reference properties from variables (instead of by type), but I find both propositions confusing. I agree that with the first version, it is very tricky on first sight to understand what is being “keypathed”. But I find the second variation syntactically very surprising for Swift and I think many people in the mailing list would have problems with it.

Here’s a potential solution: force explicit self. inside #keypath expressions:

print(#keypath(Person.bestFriend.firstName))	// => bestFriend.firstName
print(#keypath(chris.bestFriend.firstName))	// => bestFriend.firstName
print(#keypath(self.bestFriend.firstName)	// => bestFriend.firstName


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160308/b9a96cfe/attachment.html>

More information about the swift-evolution mailing list