<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=""><br class=""><div><blockquote type="cite" class=""><div class="">On Mar 22, 2017, at 11:00 AM, Vladimir.S <<a href="mailto:svabox@gmail.com" class="">svabox@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">On 22.03.2017 18:47, Matthew Johnson wrote:<br class=""><blockquote type="cite" class=""><br class=""><blockquote type="cite" class="">On Mar 22, 2017, at 10:36 AM, Vladimir.S via swift-evolution<br class=""><<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a> <<a href="mailto:swift-evolution@swift.org" class="">mailto:swift-evolution@swift.org</a>>> wrote:<br class=""><br class="">On 22.03.2017 17:37, Ricardo Parada wrote:<br class=""><blockquote type="cite" class=""><br class=""><br class=""><blockquote type="cite" class="">On Mar 22, 2017, at 9:30 AM, Vladimir.S <<a href="mailto:svabox@gmail.com" class="">svabox@gmail.com</a><br class=""><<a href="mailto:svabox@gmail.com" class="">mailto:svabox@gmail.com</a>>> wrote:<br class=""><br class="">let path = @Bag.things[0].name<br class=""><br class="">bag@path<br class="">bag@.things[0].name<br class=""><a href="mailto:bag@Bag.things" class="">bag@Bag.things</a> <<a href="mailto:bag@Bag.things" class="">mailto:bag@Bag.things</a>>[0].name<br class="">bag.things[0]@.name<br class="">bag.things[0]@Thing.name<br class=""></blockquote><br class="">It sounds like the @ character is serving two different purposes which<br class="">confused me at first.<br class=""><br class="">If I understood correctly, you are using it to get the key path but also<br class="">to apply the key path to the bag struct and get the corresponding value.<br class=""><br class=""></blockquote><br class="">Yes. And the initial proposal suggest the following syntax accordingly:<br class=""><br class="">let path = Bag.things[0].name<br class="">bag[path]<br class="">bag[.things[0].name]<br class="">bag[Bag.things[0].name]<br class="">bag.things[0][.name]<br class="">bag.things[0][Thing.name]<br class=""></blockquote><br class=""># makes a lot more sense than @ as a sigil. It follows from #selector and<br class="">#keyPath. These are the most similar language features right now where the<br class="">compiler produces special values. I think it’s also worth noticing that<br class="">values produced by #selector and #keyPath are /used/ in normal ways. There<br class="">is no magic syntax for their use, just a typed value. If we’re going to<br class="">make a change we should use # instead of `.` for accessing these special<br class="">values but we should stick with subscript for use.<br class=""></blockquote><br class="">Could you clarify, what do you suggest? Something like this:<br class="">let path = Bag#things[0]#name<br class=""></div></div></blockquote><div><br class=""></div><div>I would only use one # at the start of the key path. Dots could be used afterwords like this: `Bag#things[0].name` I think it is important to use normal expression syntax after the key path is introduced.</div><br class=""><blockquote type="cite" class=""><div class=""><div class="">bag[#path]<br class=""></div></div></blockquote><div><br class=""></div><div>No, you would just say `bag[path]`. `path` is a normal value and the subscript taking a path is a normal subscript.</div><br class=""><blockquote type="cite" class=""><div class=""><div class="">bag[#things[0]#name]<br class=""></div></div></blockquote><div><br class=""></div><div><div>Here we have a type context expecting a key path with a root of the type of `bag`. There is no potential ambiguity involved in using the `.` here unless people extend the key path types with static members themselves. I think it’s fair to say do that at your own risk. So there is no <b class="">need</b> to use special synatx - dot shorthand would work just fine with no ambiguity problem. You could imagine the compiler synthesizing static members on key path types like this:</div><div><br class=""></div><div>extension PartialKeyPath where Root == BagType {</div><div> static var things: KeyPath<Root, ThingsType> // or WriteableKeyPath or ReferenceWritableKeyPath</div><div>}</div></div><div><br class=""></div><div>You just say: `bag[.things[0]#name]` using the existing dot shorthand for static members that return a value matching the type they are declared on.</div><div><br class=""></div><div>On the other hand, it would be more consistent to introduce # shorthand here and not have the imaginary / synthesized static members on the key path types. I’m neutral, leaning towards using # shorthand for this.</div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div class="">bag[Bag#things[0]#name]</div></div></blockquote><div><br class=""></div><div>As above, there is no need for a second `#`. Once the expression has produced a key path all subsequent chained accesses will also produce a key path.</div><div><br class=""></div><div>bag[Bag#things[0].name]</div><br class=""><blockquote type="cite" class=""><div class=""><div class="">bag.things[0][#name]<br class=""></div></div></blockquote><div><br class=""></div><div>As above, here we have a type context in the subscript that expects a key path. We could use the existing dot shorthand and compiler synthesized static properties on key path types or just introduce a # shorthand. The latter is probably better for consistency.</div><br class=""><blockquote type="cite" class=""><div class=""><div class="">bag.things[0][Thing#name]<br class=""></div></div></blockquote><div><br class=""></div><div>Sure, if you don’t like the shorthand.</div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><br class="">,and so<br class="">let ref = Bag#foo()<br class=""></div></div></blockquote><div><br class=""></div><div>Yep.</div><div><br class=""></div><div>One interesting thing to note is that we could also get deep references to unbound methods. This would effectively combine key paths with unbound method references:</div><div><br class=""></div><div>let doSomething = Bag#things[0].doSomething()</div><div><br class=""></div><div>used like this:</div><div>doSomthing(bag)</div><div><br class=""></div><div>Using # for key paths also allows us to build on it in the future for collection operators:</div><div><br class=""></div><div>Bag#things[#sum].value // a key path that sums the value of all things in a bag</div><div><br class=""></div><div>Reserving this potential is one important reason to only use # where you are introducing a special key path expression and not everywhere in the key path chain.</div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><br class="">?<br class=""><br class="">In this case I feel like the following will be more clean syntax:<br class="">let path = #Bag.things[0].name<br class="">bag[#path]<br class="">bag[#.things[0].name]<br class="">bag[#Bag.things[0].name]<br class="">bag.things[0][#.name]<br class="">bag.things[0][#Thing.name]<br class="">let ref = #Bag.foo()<br class=""></div></div></blockquote><div><br class=""></div><div>This is kind of weird because Bag doesn’t have a static things property. I think it’s better to start put the # in the middle. That said, this would work as well.</div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><br class="">And why subscript is the only good candidate for use?<br class=""></div></div></blockquote><div><br class=""></div><div>It is how Swift models parameterized value access. Building on that model makes a ton of sense. I can’t imagine a compelling argument for <i class="">using</i> key path values.</div><br class=""><blockquote type="cite" class=""><div class=""><div class="">Actually, for me personally, any solution will be good as soon as it contains some 'marker' which saying "hey, here key paths are used. be aware."<br class=""><br class=""><blockquote type="cite" class=""><br class=""><blockquote type="cite" class="">_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a> <<a href="mailto:swift-evolution@swift.org" class="">mailto:swift-evolution@swift.org</a>><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></blockquote><br class=""></blockquote></div></div></blockquote></div><br class=""></body></html>