[swift-evolution] Smart KeyPaths

Michael LeHew lehewjr at apple.com
Fri Mar 17 16:21:09 CDT 2017

Hi Vladimir,

Responses inline, thank you for feedback! :)

> On Mar 17, 2017, at 11:27 AM, Vladimir.S <svabox at gmail.com> 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.

For most cases that wouldn't be a typical collision (between instance property / static/class property).  Joe, how were you thinking we'd differentiate between unexecuted static property and wanting the value of the key path?

> 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".

The subscript is serving us in a couple of ways.  For one, self is always inout for subscripts, which has important performance impact for value types (materializeForSet, e.g. not having to read the value type through the key path only to write it back).  It also allows us to have mutations share the same spelling for value and/reference properties.  We had explored having get/set methods here:

	get(from: Root) -> Value
	set(inout into: Root, _ newValue: Value) 
	set(into: Root, _ newValue: Value)

but then using a key path involved a reverse yoda-speak:

let lukesName = Person.name.get(luke)

> 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 at friends[0].name
> luke at path
> or other with help of community.

The one we worked with throughout discussions was the beloved ` from Lisp. `Person.friends[0].name  Of course, ` has its own problems, and any other character would probably work.  Upon talking with members of the Swift compiler team, they offered that we don't need an escape, and it makes for a smaller change to the language if we don't add such a thing, so we agreed. 

I do agree there is some human benefit to noting you are 'escaping' the execution; 

More information about the swift-evolution mailing list