> On 10. Jun 2017, at 01:42, Karl Wagner <razie...@gmail.com> wrote: > >> >> On 8. Jun 2017, at 04:58, Tony Allevato via swift-evolution >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >> >> +1, I really like this. It would also align nicely with the method type >> flattening in SE-0042 >> <https://github.com/apple/swift-evolution/blob/master/proposals/0042-flatten-method-types.md> >> (once it gets implemented), because passing keypaths (i.e., unbound >> property references) and unbound parameterless method references to >> map/flatMap would look nearly the same: >> >> ``` >> struct Person { >> let firstName: String >> let lastName: String >> func fullName() -> String { return "\(firstName) \(lastName)" } >> } >> >> let people: [Person] >> let firstNames = people.map(\.firstName) >> let fullNames = people.map(Person.fullName) // because after SE-0042, this >> will be (Person) -> String, not (Person) -> () -> String >> ``` >> >> Especially if there's a move in the future to also use \. to denote unbound >> methods references, which was discussed during the keypath reviews. (Even >> with that, I believe it would be more work though to get rid of the explicit >> type name in the function case.) >> >> > > When it comes to unbound method references, personally, I would love to see > us ditch currying in some future version of Swift and move to full-blown > partial application instead. We would need variadic generics if we wanted to > expose them as nicely-typed objects as we do with KeyPaths. > > Anyway, I think what you want is something like this (where VirtualKeyPath is > a custom subclass of KeyPath which is lazily-evaluated using a closure). > > extension KeyPath where Value: Collection { > func map<T>(_ descendent: KeyPath<Value, T>) -> VirtualKeyPath<Root, [T]> > { > return VirtualKeyPath<Root, [T]> { > (obj: Root) -> [T] in obj[keypath: self].map { $0[keypath: > descendent] } > } > } > } > > \Department.people.map(\.fullName).characters.count // type: > VirtualKeyPath<Department, [Int]> > > > Custom subclasses of KeyPath are not allowed, so you can’t actually do this. > I don’t know, maybe it wouldn’t be much overhead to add the one, > closure-based VirtualKeyPath — clearly the architecture is meant to be > flexible. Maybe it’s better to wait until Swift 5 for that, though. > > - Karl
Two corrections to myself: 1) It’s KeyPath<Value.Element, T> 2) You could implement VirtualKeyPath today, but you wouldn’t get the chaining syntax. You’d have to just keep map-ping it every time: \Department.people.map(\.fullName).map(\.characters.count) // type: VirtualKeyPath<Department, [Int]> - Karl > >> On Wed, Jun 7, 2017 at 6:11 PM Xiaodi Wu via swift-evolution >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >> +1. Would think that all variants should exist on Optional too unless it >> would be harmful. >> On Wed, Jun 7, 2017 at 20:13 Michael J LeHew Jr via swift-evolution >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >> This is a great idea, and ought to be easy enough to bring forward! +1 from >> me! >> >> -Michael >> >> > On Jun 7, 2017, at 11:18 AM, Matt Diephouse via swift-evolution >> > <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >> > >> > 💯 >> > >> >> On Jun 7, 2017, at 10:35 AM, Adam Sharp via swift-evolution >> >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >> >> >> >> The new smart key path feature is really lovely, and feels like a great >> >> addition to Swift. >> >> >> >> It seems like it might be straightforward to add overloads of `map` and >> >> `flatMap` to the standard library to make use of the new functionality: >> >> >> >> let managers = flatOrganisation.managers >> >> let allEmployees = Set(managers.flatMap(\.directReports)) >> >> let employeeNames = Set(allEmployees.map(\.name)) >> >> >> >> This feels like a really natural way of working with key paths in a >> >> functional style. It makes a lot of sense for collections, and possibly >> >> for Optional too (although as far as I can see optional chaining is more >> >> or less equivalent, and with more compact syntax). >> >> >> >> I’m hoping that this might be low-hanging fruit that could be considered >> >> for the Swift 4 release. I’d be happy to have a go at writing a proposal >> >> if there’s interest! >> >> >> >> –Adam >> >> >> >> _______________________________________________ >> >> swift-evolution mailing list >> >> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >> >> https://lists.swift.org/mailman/listinfo/swift-evolution >> >> <https://lists.swift.org/mailman/listinfo/swift-evolution> >> > >> > _______________________________________________ >> > swift-evolution mailing list >> > swift-evolution@swift.org <mailto:swift-evolution@swift.org> >> > https://lists.swift.org/mailman/listinfo/swift-evolution >> > <https://lists.swift.org/mailman/listinfo/swift-evolution> >> >> _______________________________________________ >> swift-evolution mailing list >> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >> https://lists.swift.org/mailman/listinfo/swift-evolution >> <https://lists.swift.org/mailman/listinfo/swift-evolution> >> _______________________________________________ >> swift-evolution mailing list >> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >> https://lists.swift.org/mailman/listinfo/swift-evolution >> <https://lists.swift.org/mailman/listinfo/swift-evolution> >> _______________________________________________ >> swift-evolution mailing list >> 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