<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div><blockquote type="cite" class=""><div class="">On Aug 25, 2017, at 3:54 PM, Logan Shire &lt;<a href="mailto:logan.shire@gmail.com" class="">logan.shire@gmail.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">How would you feel about wrapping the existing functions on&nbsp;_KVOKeyPathBridgeMachinery:<div class=""><br class=""><div class="">@nonobjc fileprivate static func _bridgeKeyPath(_ keyPath:AnyKeyPath) -&gt; String</div><div class="">@nonobjc fileprivate static func _bridgeKeyPath(_ keyPath:String?) -&gt; AnyKeyPath?</div><div class=""><br class=""></div><div class="">In extensions on String and AnyKeyPath respectively to instantiate strings from KeyPaths and KeyPaths from Strings?</div></div></div></div></blockquote><div><br class=""></div><div>Those functions are designed for Cocoa interop only. They're not going to produce results that make sense for all Swift key paths.<br class=""><div><blockquote type="cite" class=""></blockquote></div></div><div><br class=""></div><div>-Joe</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><div class=""><a href="https://github.com/apple/swift/blob/c5ff1f2cac8da6a14330f4b033b94c7c926d2126/stdlib/public/SDK/Foundation/NSObject.swift#L84" class="">https://github.com/apple/swift/blob/c5ff1f2cac8da6a14330f4b033b94c7c926d2126/stdlib/public/SDK/Foundation/NSObject.swift#L84</a><br class=""></div><div class=""><br class=""><div class="gmail_quote"><div dir="ltr" class="">On Fri, Aug 25, 2017 at 11:43 AM Joe Groff &lt;<a href="mailto:jgroff@apple.com" class="">jgroff@apple.com</a>&gt; wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br class="">
&gt; On Aug 23, 2017, at 11:18 PM, Logan Shire via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; wrote:<br class="">
&gt;<br class="">
&gt; Hey folks!<br class="">
&gt;<br class="">
&gt; Recently I’ve been working on a small library which leverages the Swift 4 Codable protocol<br class="">
&gt; and KeyPaths to provide a Swift-y interface to CoreData. (It maps back and forth between<br class="">
&gt; native, immutable Swift structs and NSManagedObjects). In doing so I found a couple of<br class="">
&gt; frustrating limitations to the KeyPath API. Firstly, KeyPath does not provide the name of the<br class="">
&gt; property on the type it indexes. For example, if I have a struct:<br class="">
&gt;<br class="">
&gt;<br class="">
&gt; struct Person {<br class="">
&gt;&nbsp; &nbsp; let firstName: String<br class="">
&gt;&nbsp; &nbsp; let lastName: String<br class="">
&gt; }<br class="">
&gt;<br class="">
&gt; let keyPath = \Person.firstName<br class="">
&gt;<br class="">
&gt;<br class="">
&gt; But once I have a keyPath, I can’t actually figure out what property it accesses.<br class="">
&gt; So, I wind up having to make a wrapper:<br class="">
&gt;<br class="">
&gt;<br class="">
&gt; struct Attribute {<br class="">
&gt;&nbsp; &nbsp; let keyPath: AnyKeyPath<br class="">
&gt;&nbsp; &nbsp; let propertyName: String<br class="">
&gt; }<br class="">
&gt;<br class="">
&gt; let firstNameAttribute = Attribute(keyPath: \Person.firstName, propertyName: “firstName”)<br class="">
&gt;<br class="">
&gt;<br class="">
&gt; This forces me to write out the property name myself as a string which is very error prone.<br class="">
&gt; All I want is to be able to access:<br class="">
&gt;<br class="">
&gt;<br class="">
&gt; keyPath.propertyName // “firstName”<br class="">
&gt;<br class="">
&gt;<br class="">
&gt; It would also be nice if we provided the full path as a string as well:<br class="">
&gt;<br class="">
&gt;<br class="">
&gt; keyPath.fullPath // “Person.firstName"<br class="">
&gt;<br class="">
&gt;<br class="">
&gt; Also, if I want to get all of the attributes from a given Swift type, my options are to try to hack<br class="">
&gt; something together with Mirrors, or forcing the type to declare a function / computed property<br class="">
&gt; returning an array of all of its key path / property name pairings. I would really like to be able to<br class="">
&gt; retrieve a type-erased array of any type’s key paths with:<br class="">
&gt;<br class="">
&gt;<br class="">
&gt; let person = Person(firstName: “John”, lastName: “Doe”)<br class="">
&gt; let keyPaths = Person.keyPaths<br class="">
&gt; let firstNameKeyPath = keyPaths.first { $0.propertyName = “firstName” } as! KeyPath&lt;Person, String&gt;<br class="">
&gt; let firstName = person[keypath: firstNameKeyPath] // “John"<br class="">
&gt;<br class="">
&gt;<br class="">
&gt; And finally, without straying too far into Objective-C land, it would be nice if we could initialize key paths<br class="">
&gt; with a throwing initializer.<br class="">
&gt;<br class="">
&gt;<br class="">
&gt; let keyPath = try Person.keyPath(“firstName”) // KeyPath&lt;Person, String&gt; type erased to AnyKeyPath<br class="">
&gt; let keyPath = AnyKeyPath(“Person.firstName”)<br class="">
&gt;<br class="">
&gt;<br class="">
&gt; Let me know what you think about any / all of these suggestions!<br class="">
<br class="">
These would all be great additional features to eventually add to key paths. I think reflection mechanisms centered on key paths like what you describe would be a superior replacement for most of what Mirror attempts to provide.<br class="">
<br class="">
-Joe</blockquote></div></div></div></div>
</div></blockquote></div><br class=""></body></html>