On 22.03.2017 19:25, Matthew Johnson wrote:

On Mar 22, 2017, at 11:00 AM, Vladimir.S <sva...@gmail.com
<mailto:sva...@gmail.com>> wrote:

On 22.03.2017 18:47, Matthew Johnson wrote:

On Mar 22, 2017, at 10:36 AM, Vladimir.S via swift-evolution
<swift-evolution@swift.org <mailto:swift-evolution@swift.org>
<mailto:swift-evolution@swift.org>> wrote:

On 22.03.2017 17:37, Ricardo Parada wrote:


On Mar 22, 2017, at 9:30 AM, Vladimir.S <sva...@gmail.com
<mailto:sva...@gmail.com>
<mailto:sva...@gmail.com>> wrote:

let path = @Bag.things[0].name

bag@path
bag@.things[0].name
bag@Bag.things <mailto:bag@Bag.things> <mailto:bag@Bag.things>[0].name
bag.things[0]@.name
bag.things[0]@Thing.name

It sounds like the @ character is serving two different purposes which
confused me at first.

If I understood correctly, you are using it to get the key path but also
to apply the key path to the bag struct and get the corresponding value.


Yes. And the initial proposal suggest the following syntax accordingly:

let path = Bag.things[0].name
bag[path]
bag[.things[0].name]
bag[Bag.things[0].name]
bag.things[0][.name]
bag.things[0][Thing.name]

# makes a lot more sense than @ as a sigil.  It follows from #selector and
#keyPath.  These are the most similar language features right now where the
compiler produces special values.  I think it’s also worth noticing that
values produced by #selector and #keyPath are /used/ in normal ways.  There
is no magic syntax for their use, just a typed value.  If we’re going to
make a change we should use # instead of `.` for accessing these special
values but we should stick with subscript for use.

Could you clarify, what do you suggest? Something like this:
let path = Bag#things[0]#name

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.


Generally agree.

bag[#path]

No, you would just say `bag[path]`.  `path` is a normal value and the
subscript taking a path is a normal subscript.

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. I believe this feature deserves some highlighting with special syntax even on usage site. And subscript in this case IMO is not "normal" subscript - but "special" subscript generated by compiler to work with key path.


Vladimir.


bag[#things[0]#name]

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 *need* 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:

extension PartialKeyPath where Root == BagType {
    static var things: KeyPath<Root, ThingsType>  // or WriteableKeyPath
or ReferenceWritableKeyPath
}

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.

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.


bag[Bag#things[0]#name]

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.

bag[Bag#things[0].name]

bag.things[0][#name]

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.

bag.things[0][Thing#name]

Sure, if you don’t like the shorthand.


,and so
let ref = Bag#foo()

Yep.

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:

let doSomething = Bag#things[0].doSomething()

used like this:
doSomthing(bag)

Using # for key paths also allows us to build on it in the future for
collection operators:

Bag#things[#sum].value //  a key path that sums the value of all things in
a bag

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.


?

In this case I feel like the following will be more clean syntax:
let path = #Bag.things[0].name
bag[#path]
bag[#.things[0].name]
bag[#Bag.things[0].name]
bag.things[0][#.name]
bag.things[0][#Thing.name]
let ref = #Bag.foo()

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.


And why subscript is the only good candidate for use?

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
/using/ key path values.

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."


_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
<mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to