Proposal Link: 
https://github.com/apple/swift-evolution/blob/master/proposals/0161-key-paths.md
 
<https://github.com/apple/swift-evolution/blob/master/proposals/0161-key-paths.md>

Hello Swift community,

The review of SE-0161 “Smart KeyPaths: Better Key-Value Coding for Swift” ran 
from March 30...April 5, 2017. The proposal was very well-received *except* 
that reviewers felt that the #keyPath syntax was far too heavy for this new 
language construct, and preferred the lighter-weight syntax of the pre-review 
drafts. This proposal is returned for revision to address the syntax.

The heavyweight #keyPath syntax was requested by the core team after reviewing 
earlier drafts, which used a far lighter syntax:

        // (Rejected) syntax from pre-review drafts
        let firstFriendsNameKeyPath = Person.friends[0].name
        print(luke[keyPath: .friends[0].name])

The core team’s specific concern was that these key path expressions (e.g., 
Person.friends[0].name) don’t make it sufficiently clear that the actual 
property accesses are being delayed, and that the contextual cues (“Person." 
vs. “luke.”) are insufficient to disambiguate for the human reader. Hence, the 
request for a different (more explicit) syntax.

Reviewers rightly point out that it is natural for key-paths to use the same 
syntax as unapplied instance method references, e.g., Person.someInstanceMethod 
produces a value of some function type with the “Self” type curried, e.g., 
(Person) -> (param-types) -> result-type. The core team agrees with this 
sentiment. The core team also felt that Swift’s existing unapplied method 
references suffer from the same clarity problems as the initial key-path 
syntax, i.e., that it isn’t sufficiently clear that the actual application of 
“self” is being delayed.

The core team has a specific proposal: use the backslash (‘\’) to as a leading 
indicator for key paths. Specifically,

        // Proposed syntax for second revision
        let firstFriendsNameKeyPath = \Person.friends[0].name
        print(luke[keyPath: \.friends[0].name])

The backslash is a visual cue that the actual application of this chain of 
property references is delayed, eliminating ambiguities, yet is still quite 
lightweight and feels “first-class” in the language.

The core team felt that, in the future, the backslash should also be used for 
unapplied instance method references, to match the proposed syntax for key 
paths and improve clarity for this non obvious feature. This change could be 
staged in as a revision to the accepted-but-never-implemented SE-0042: 
Flattening the function type of unapplied method references 
<https://github.com/apple/swift-evolution/blob/master/proposals/0042-flatten-method-types.md>,
 e.g.,

        // Proposed future syntax for unapplied instance method references
        class Person {
          func instanceMethod(_: String) -> Int { … }
        }

        let f1 = Person.instanceMethod   // to-be-deprecated; produces a value 
of type (Person) -> (String) -> Int
        let f2 = \Person.instanceMethod  // to-be-introduced via a revised 
SE-0042: produces a value of type (Person, String) -> Int

Such an approach gives us a way to stage in SE-0042 and get to eventual 
consistency between key paths and unapplied instance method references.

        - Doug
        Review Manager






_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to