> On Mar 29, 2017, at 5:12 PM, James Berry <[email protected]> wrote: > >> Referencing Key Paths >> >> Forming a KeyPath borrows from the same syntax added in Swift 3 to confirm >> the existence of a given key path, only now producing concrete values >> instead of Strings. Optionals are handled via optional-chaining. Multiply >> dotted expressions are allowed as well, and work just as if they were >> composed via the appending methods on KeyPath. >> >> There is no change or interaction with the #keyPath() syntax introduced in >> Swift 3. #keyPath(Person.bestFriend.name) will still produce a String, >> whereas #keyPath(Person, .bestFriend.name) will produce a KeyPath<Person, >> String>. > > This distinction seems arbitrary and confusing. The user is supposed tor > remember that the #keyPath(Person.bestFriend.name) form produces a string > while the #keyPath(Person, .bestFriend.name) form produces a key path object? > I don’t think we’re advancing here. What would be the effect if just the > former was valid, and (always/now) produced a keypath object that was > convertible to string? How bad would the breakage be?
The syntax subtleties here are unfortunate. An idea that we discussed was to be able to tell when a #keyPath wants to be considered as a string and either implicitly or having some affordance for doing so. Back then this was harder because we had #keyPaths that could not be represented as a string (an earlier draft had keyPaths that could compose with closures; which while powerful, weren't really key paths any more. That idea was removed from the proposal we shared as they are intrinsically opposed to being able to serializing/deserialize key paths). Given that we don't support those kinds of key paths, nor are we really considering adding them back thanks to our desire to support serializing key paths to file in the future, this is a very reasonable idea I think. > > James > > > >> On Mar 29, 2017, at 4:13 PM, Michael J LeHew Jr via swift-evolution >> <[email protected] <mailto:[email protected]>> wrote: >> >> Thanks for the feedback everyone! We have pushed a changed a bit ago to the >> proposal reflecting these desires. >> >> https://github.com/apple/swift-evolution/pull/644/files >> <https://github.com/apple/swift-evolution/pull/644/files> >> >> -Michael >> >>> On Mar 29, 2017, at 2:49 PM, Douglas Gregor <[email protected] >>> <mailto:[email protected]>> wrote: >>> >>> >>>> On Mar 17, 2017, at 10:04 AM, Michael LeHew via swift-evolution >>>> <[email protected] <mailto:[email protected]>> wrote: >>>> >>>> Hi friendly swift-evolution folks, >>>> >>>> The Foundation and Swift team would like for you to consider the >>>> following proposal: >>> >>> >>> The Swift core team discussed this proposal draft and had a little bit of >>> pre-review feedback. >>> >>>> Access and Mutation Through KeyPaths >>>> To get or set values for a given root and key path we effectively add the >>>> following subscripts to all Swift types. >>>> >>>> Swift >>>> extension Any { >>>> subscript(path: AnyKeyPath) -> Any? { get } >>>> subscript<Root: Self>(path: PartialKeyPath<Root>) -> Any { get } >>>> subscript<Root: Self, Value>(path: KeyPath<Root, Value>) -> Value { >>>> get } >>>> subscript<Root: Self, Value>(path: WritableKeyPath<Root, Value>) -> >>>> Value { set, get } >>>> } >>> >>> Swift doesn’t currently have the ability to extend Any, so this is >>> (currently) pseudocode for compiler magic that one day we might be able to >>> place. Additionally, the “Root: Self” constraint isn’t something we support >>> in the generics system. A small note indicating that this is pseudo-code >>> meant to get the point across (rather than real code to drop into the >>> standard library/Foundation) would be appreciated. >>> >>> More importantly, this adds an unlabeled subscript to every type, which >>> raises concerns about introducing ambiguities—even if not hard ambiguities >>> that prevent code from compiling (e.g., from a Dictionary<AnyKeyPath, >>> …>)---they can still show up in code completion, diagnostics, etc. >>> >>> The core team would prefer that this subscript distinguish itself more, >>> e.g., by labeling the first parameter “keyPath” (or some better name, if >>> there is one). Syntactically, that would look like: >>> >>> person[keyPath: theKeyPathIHave] >>> >>>> Referencing Key Paths >>>> >>>> Forming a KeyPath borrows from the same syntax used to reference methods >>>> and initializers,Type.instanceMethod only now working for properties and >>>> collections. Optionals are handled via optional-chaining. Multiply dotted >>>> expressions are allowed as well, and work just as if they were composed >>>> via the appending methods on KeyPath. >>>> >>> The core team was concerned about the use of the Type.instanceProperty >>> syntax for a few reasons: >>> >>> * It doesn’t work for forming keypaths to class/static properties (or >>> is ambiguous with the existing meaning(, so we would need another syntax to >>> deal with that case >>> * It’s quite subtle, even more so that the existing Type.instanceMethod >>> syntax for currying instance methods >>> >>>> There is no change or interaction with the #keyPath() syntax introduced in >>>> Swift 3. >>>> >>> The core team felt that extending the #keyPath syntax was a better >>> syntactic direction to produce key-paths. >>> >>> - Doug >>> >> >> _______________________________________________ >> swift-evolution mailing list >> [email protected] <mailto:[email protected]> >> https://lists.swift.org/mailman/listinfo/swift-evolution >
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
