google / promises

Promises is a modern framework that provides a synchronization construct for Swift and Objective-C.
Apache License 2.0
3.8k stars 293 forks source link

Map extension #68

Closed zontag closed 6 years ago

zontag commented 6 years ago

There is any intention to provide a Map extension?

shoumikhin commented 6 years ago

Hi Tiago,

What kind of a Map extension would you like to see? Any examples? Perhaps we already have what you need?

Thanks.

zontag commented 6 years ago

Hi Tiago,

What kind of a Map extension would you like to see? Any examples? Perhaps we already have what you need?

Thanks.

I'm converting my project from PromiseKit to Promises and in some places where I used PromiseKit extensions like map, mapValues, compactMap and compactMapValues was needed some more imperative code. Maybe I'm missing something but here are a code comparation. Note that I opted for explicit closure typed because compiler was pain on guess it.

return userDBManager
                .getAll(.promise)
                .compactMap(on: bgq) { $0.first }
                .compactMap(on: bgq) { $0.selectedMachines }
                .compactMapValues(on: bgq) { $0 as? MachineMO } // Casting
                .mapValues(on: bgq, toMachine)
                .recover { _ in Guarantee.value([]) }

agains

return userDBManager
                .getAllPromise()
                .then(on: bgq) { $0.first }
                .validate(on: bgq) { $0 != nil }
                .then(on: bgq) { (user: UserMO?) -> NSSet? in
                    user!.selectedMachines
                }
                .validate(on: bgq) { $0 != nil }
                .then(on: bgq) { (set: NSSet?) -> [MachineMO] in
                    set!.compactMap { $0 as? MachineMO }
                }.then(on: bgq) { (entities: [MachineMO]) -> [Machine] in
                    entities.compactMap(toMachine)
                }.recover { _ in [Machine]() }

Same without explicit types:

return userDBManager
                .getAllPromise()
                .then(on: bgq) { $0.first }
                .validate(on: bgq) { $0 != nil }
                .then(on: bgq) { user!.selectedMachines }
                .validate(on: bgq) { $0 != nil }
                .then(on: bgq) { set!.compactMap { $0 as? MachineMO } }
                .then(on: bgq) { entities.compactMap(toMachine) }
                .recover { _ in [Machine]() }
shoumikhin commented 6 years ago

Many thanks for the example! Wonder if you could leverage nil-coalescing for all of that instead?

return userDBManager.getAllPromise().then(on: bgq) {
  $0?.first?.selectedMachines?.compactMap { $0 as? MachineMO }?.compactMap(toMachine) ?? []
}
zontag commented 6 years ago

Really better, great solution! It solved the problem and keeps the code elegant and simple. Thanks!