[Review] SE-0062: Referencing Objective-C key-paths


(Douglas Gregor) #1

Hello Swift community,

The review of SE-0062 “Referencing Objective-C key-paths" begins now and runs through April 12, 2016. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0062-objc-keypaths.md
Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

Proposal link:

https://github.com/apple/swift-evolution/blob/master/proposals/0062-objc-keypaths.md
Reply text

Other replies
<https://github.com/apple/swift-evolution#what-goes-into-a-review-1>What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

What is your evaluation of the proposal?
Is the problem being addressed significant enough to warrant a change to Swift?
Does this proposal fit well with the feel and direction of Swift?
If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
More information about the Swift evolution process is available at

https://github.com/apple/swift-evolution/blob/master/process.md
Thank you,

-Doug Gregor

Review Manager


(Brent Royal-Gordon) #2

https://github.com/apple/swift-evolution/blob/master/proposals/0062-objc-keypaths.md

  • What is your evaluation of the proposal?

I'm definitely in favor and look forward to using #keyPath. I have one note, one suggestion and one concern, but even without any of them being addressed, I would want to see this proposal become part of Swift.

* * *

The note: The Collection crossing might apply only to types which offer `Index -> Element` and `Range<Index> -> SubSequence` subscripts, but no others. That would include Array and Set but exclude Dictionary.

On the other hand, NSDictionary *does* have KVC behavior: the particular key is unconstrained and it always results in an instance of the dictionary's ObjectType. #keyPath could usefully support that in some way.

* * *

The suggestion: Many key paths are immediately passed to methods on the object they will eventually act on. For example:

  chris.value(forKeyPath: #keyPath(Person.friends.firstName))

It would be nice if we could use leading dot to refer to the type of the object the key path is being passed to:

  chris.value(forKeyPath: #keyPath(.friends.firstName))

Leading dot does not have any other useful meaning in this context; it would always refer to a static variable on String, which is not a sensible key path to try to construct.

* * *

The concern: I'm a little worried that the "value expression" feature can be ambiguous when accessing properties of `self`. Consider these expressions (as they might appear in the `Person.find(name:)` example):

  #keyPath(firstName.uppercased) => "firstName.uppercased"
  #keyPath(name.uppercased) => "uppercased"

Although they look quite similar, they end up giving very different behaviors because `firstName` is a property while `name` is a variable. I think this could be misleading—particularly because it'll be tempting to say things like this:

  firstName.value(forKeyPath: #keyPath(firstName.uppercased)) // oops, that's getting `self.firstName.firstName.uppercased`!

I see two simple but inconsistent alternatives here, and one which is more complex but also more consistent:

1. Require `self` for a property's key path. This makes it clear that you're going to get "firstName.uppercased", but it's a little inconvenient in the plain `firstName` case, which isn't ambiguous.

2. Require `self` for a property's key path only when there are additional parts to the key path. In other words, you can say `#keyPath(firstName)`, but firstName.uppercased's keypath has to be written `#keyPath(self.firstName.uppercased)`. This removes the inconvenience of #1, but it's a complicated rule to explain.

3. Change the syntax entirely so that the thing you're looking for the key path of goes before the #keyPath keyword. This would make it crystal clear which part is the key path and which part merely specifies the type the key path will be used on; it would also allow you to use a more complicated expression to provide the type. Examples:

  Person.#keyPath(firstName.uppercased)
  self.#keyPath(firstName.uppercased)
  #keyPath(firstName.uppercased) // Implicit `self`
  
  // Here's an example of a complicated path to the object you want to work from
  textView.layoutManager.typesetter.#keyPath(usesFontLeading)
  
  // The leading dot feature I asked for would look like:
  chris.value(forKeyPath: .#keyPath(friends.firstName))

This looks weird when you're not used to it, but it's not really that strange an idea conceptually; if #foo() is a compile-time function, this is a compile-time method.

* * *

Despite these concerns, I really like this proposal a lot, and I hope to see it be accepted.

  • Is the problem being addressed significant enough to warrant a change to Swift?

Yes. Simply put, stringly-typed code is a menace, but often a necessary one. Anything that makes it safer is a winner in my book.

  • Does this proposal fit well with the feel and direction of Swift?

Yes. It's particularly reminiscent of #selector, but it actually goes further by providing a feature people had to hack into Objective-C with horrible macros.

  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

That's...actually kind of an interesting question. But my thoughts on that matter are not on topic for this review, so for now I'll say no, I don't have any relevant experience.

(Well, I have seen various horrible macros which offer some semblance of typo safety for KVC. But these are best not spoken of.)

  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

I read the proposal and participated in the discussion.

···

--
Brent Royal-Gordon
Architechies


(plx) #3

What is your evaluation of the proposal?

I like it and think it’s something Swift should definitely have.

A quibble: I think there’d be value in also having:

   #key(ClassName.propertyName)

…which is the same as `#keyPath`, but without support for *paths*.

It’s functionally-redundant with the more-general #keyPath but makes intent clearer, and is IMHO both shorter and clearer at any call-site that require keys, not key-paths.

Is the problem being addressed significant enough to warrant a change to Swift?

Yes for the same reasons #selector was added.

Does this proposal fit well with the feel and direction of Swift?

Yes.

If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Quick read, didn’t follow the lead-up discussion.

···

More information about the Swift evolution process is available at

https://github.com/apple/swift-evolution/blob/master/process.md
Thank you,

-Doug Gregor

Review Manager

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


(Rudolf Adamkovič) #4

A very big +1 from me!

This proposal will have a significant impact on majority of Cocoa developers. To mention one thing, all Core Data stuff (predicates, search descriptors) will become much safer. I'm strongly in favor. Let's do this!

···

Sent from my iPhone

On 07 Apr 2016, at 18:48, Douglas Gregor <dgregor@apple.com> wrote:

Hello Swift community,

The review of SE-0062 “Referencing Objective-C key-paths" begins now and runs through April 12, 2016. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0062-objc-keypaths.md
Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

Proposal link:

https://github.com/apple/swift-evolution/blob/master/proposals/0062-objc-keypaths.md
Reply text

Other replies
What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

What is your evaluation of the proposal?
Is the problem being addressed significant enough to warrant a change to Swift?
Does this proposal fit well with the feel and direction of Swift?
If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
More information about the Swift evolution process is available at

https://github.com/apple/swift-evolution/blob/master/process.md
Thank you,

-Doug Gregor

Review Manager

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