> On Apr 7, 2017, at 11:48 AM, John McCall <rjmcc...@apple.com> wrote: > >> On Apr 7, 2017, at 1:40 PM, Joe Groff <jgr...@apple.com> wrote: >>> On Apr 7, 2017, at 10:20 AM, John McCall via swift-evolution >>> <swift-evolution@swift.org> wrote: >>> >>>> >>>> On Apr 7, 2017, at 12:48 AM, Douglas Gregor <dgre...@apple.com> wrote: >>>> >>>> >>>>> On Apr 6, 2017, at 9:46 PM, John McCall <rjmcc...@apple.com> wrote: >>>>> >>>>>> On Apr 7, 2017, at 12:27 AM, Rick Mann <rm...@latencyzero.com> wrote: >>>>>>> On Apr 6, 2017, at 20:37 , John McCall <rjmcc...@apple.com> wrote: >>>>>>> >>>>>>>> On Apr 6, 2017, at 9:28 PM, Rick Mann via swift-evolution >>>>>>>> <swift-evolution@swift.org> wrote: >>>>>>>> I tend to dislike the backslash as well, but can't suggest a good >>>>>>>> alternative. >>>>>>>> >>>>>>>> Does any of this allow for operations within the key path? e.g. >>>>>>>> Department.employees.@sum.salary? >>>>>>> >>>>>>> You can express things like this in the feature as proposed using >>>>>>> subscripts: >>>>>>> >>>>>>> extension Collection { >>>>>>> subscript<T: Integer>(summing path: KeyPath<Element, T>) -> T { >>>>>>> var sum: T = 0 >>>>>>> for let elt in self { >>>>>>> sum += elt[keyPath: path] >>>>>>> } >>>>>>> return sum >>>>>>> } >>>>>>> } >>>>>> >>>>>> I'm just remembering how AppKit/Cocoa lets you do things like this in a >>>>>> very expressive way. Your proposal seems a bit cumbersome. Maybe when we >>>>>> have custom annotations, they can be extended to use within key paths. >>>>> >>>>> I'm not seriously endorsing this exact spelling. It would be much better >>>>> to be able to write something like: >>>>> \Department.employees.sum(of: \.salary) >>>>> However, since "sum" would presumably be a method on Collection, I think >>>>> this would have to be a future extension to the proposal, and the overall >>>>> thing might have to be a function rather than a key path because it would >>>>> no longer have identity. >>>> >>>> Also, less clever but potentially easier to reason about: >>>> >>>> extension Array where Element == Employee { >>>> var sumOfSalary: Double { >>>> return // ... >>>> } >>>> } >>>> >>>> If you can express it in a computed property, you can refer to it via a >>>> key path: >>>> >>>> \Department.employees.sumOfSalary >>> >>> Yeah, you can, but that's definitely an expressivity hit. >> >> True, but there are some benefits to requiring a subscript/property rather >> than an arbitrary closure, particularly that it gives the operation a stable >> identity and structure so the key path can still be equated/hashed and >> (eventually) iterated through. > > Right, I think if you add a method to the chain, the result definitely has to > be a function rather than a key path. The idea is that you basically > decompose: > > \Base.A.B.C > > into > ([inout]? Base, parameters(A)..., parameters(B)..., parameters(C)...) -> > result(C) > > except that if all of the components A, B, and C are just properties or > applied subscripts you can make it a KeyPath<Base,C> instead, which can then > contextually devolve into a function.
It seems to me that method references (non-mutating ones, at least) could still be treated as read-only key path components. There's not much more than syntax as a difference between a nonmutating method and get-only property or subscript. The method decl is still something we can ascribe identity to. -Joe _______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution