<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 12:34 PM, 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 19:25, Matthew Johnson wrote:<br class=""><blockquote type="cite" class=""><br class=""><blockquote type="cite" class="">On Mar 22, 2017, at 11:00 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="">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>><br class=""><<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>><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>> <<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=""></blockquote><br class="">I would only use one # at the start of the key path. Dots could be used<br class="">afterwords like this: `Bag#things[0].name` I think it is important to use<br class="">normal expression syntax after the key path is introduced.<br class=""><br class=""></blockquote><br class="">Generally agree.<br class=""><br class=""><blockquote type="cite" class=""><blockquote type="cite" class="">bag[#path]<br class=""></blockquote><br class="">No, you would just say `bag[path]`. `path` is a normal value and the<br class="">subscript taking a path is a normal subscript.<br class=""></blockquote><br class="">That was my main intention - to discuss if we should add some special marker when we create *and* also use key path. To remove confusion when you see 'instance[something]' in one's code and can't be sure if we access a "normal" subscript or 'something' is a key path. Especially if instance is array/dictionary or other collection.<br class="">I believe this feature deserves some highlighting with special syntax even on usage site.<br class="">And subscript in this case IMO is not "normal" subscript - but "special" subscript generated by compiler to work with key path.<br class=""></div></div></blockquote><div><br class=""></div><div>The fact that this is a key path exists in the type system and is readily available. It also likely exists in the variable name. We don’t use special syntax when we work with a selector or a KVC key path. I don’t think we should use special syntax here either.</div><div><br class=""></div><div>The compiler will synthesizes these subscripts but it also synthesizes other code for us now and will synthesize even more in the future. I don’t see compiler synthesis as a compelling reason for using special syntax. The reason it makes some sense for creating the values is because they are values of a special type that <i class="">only</i> the compiler can create.</div><div><br class=""></div><div>One option would be to include `get` and `set` methods on the key path types. That would allow us to write the subscripts in the standard library (if it is allowed to extend Any) and keep <i class="">all</i> of the magic in the key path types themselves. I think I would like that approach.</div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><br class=""><br class="">Vladimir.<br class=""><br class=""><blockquote type="cite" class=""><br class=""><blockquote type="cite" class="">bag[#things[0]#name]<br class=""></blockquote><br class="">Here we have a type context expecting a key path with a root of the type of<br class="">`bag`. There is no potential ambiguity involved in using the `.` here<br class="">unless people extend the key path types with static members themselves. I<br class="">think it’s fair to say do that at your own risk. So there is no *need* to<br class="">use special synatx - dot shorthand would work just fine with no ambiguity<br class="">problem. You could imagine the compiler synthesizing static members on key<br class="">path types like this:<br class=""><br class="">extension PartialKeyPath where Root == BagType {<br class=""> static var things: KeyPath<Root, ThingsType> // or WriteableKeyPath<br class="">or ReferenceWritableKeyPath<br class="">}<br class=""><br class="">You just say: `bag[.things[0]#name]` using the existing dot shorthand for<br class="">static members that return a value matching the type they are declared on.<br class=""><br class="">On the other hand, it would be more consistent to introduce # shorthand<br class="">here and not have the imaginary / synthesized static members on the key<br class="">path types. I’m neutral, leaning towards using # shorthand for this.<br class=""><br class=""><br class=""><blockquote type="cite" class="">bag[Bag#things[0]#name]<br class=""></blockquote><br class="">As above, there is no need for a second `#`. Once the expression has<br class="">produced a key path all subsequent chained accesses will also produce a key<br class="">path.<br class=""><br class="">bag[Bag#things[0].name]<br class=""><br class=""><blockquote type="cite" class="">bag.things[0][#name]<br class=""></blockquote><br class="">As above, here we have a type context in the subscript that expects a key<br class="">path. We could use the existing dot shorthand and compiler synthesized<br class="">static properties on key path types or just introduce a # shorthand. The<br class="">latter is probably better for consistency.<br class=""><br class=""><blockquote type="cite" class="">bag.things[0][Thing#name]<br class=""></blockquote><br class="">Sure, if you don’t like the shorthand.<br class=""><br class=""><blockquote type="cite" class=""><br class="">,and so<br class="">let ref = Bag#foo()<br class=""></blockquote><br class="">Yep.<br class=""><br class="">One interesting thing to note is that we could also get deep references to<br class="">unbound methods. This would effectively combine key paths with unbound<br class="">method references:<br class=""><br class="">let doSomething = Bag#things[0].doSomething()<br class=""><br class="">used like this:<br class="">doSomthing(bag)<br class=""><br class="">Using # for key paths also allows us to build on it in the future for<br class="">collection operators:<br class=""><br class="">Bag#things[#sum].value // a key path that sums the value of all things in<br class="">a bag<br class=""><br class="">Reserving this potential is one important reason to only use # where you<br class="">are introducing a special key path expression and not everywhere in the key<br class="">path chain.<br class=""><br class=""><blockquote type="cite" 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=""></blockquote><br class="">This is kind of weird because Bag doesn’t have a static things property. I<br class="">think it’s better to start put the # in the middle. That said, this would<br class="">work as well.<br class=""><br class=""><blockquote type="cite" class=""><br class="">And why subscript is the only good candidate for use?<br class=""></blockquote><br class="">It is how Swift models parameterized value access. Building on that model<br class="">makes a ton of sense. I can’t imagine a compelling argument for<br class="">/using/ key path values.<br class=""><br class=""><blockquote type="cite" class="">Actually, for me personally, any solution will be good as soon as it<br class="">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="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></blockquote><br class=""></blockquote></div></div></blockquote></div><br class=""></body></html>