async(.promise) and promises (docs still accurate?)
There's a blurb at the end of the Appendix document that reads:
So, if you want to start a chain by dispatching to the background, you have to use
DispatchQueue.async:DispatchQueue.global().async(.promise) { return value }.done { value in //… }However, this function cannot return a promise because of Swift compiler ambiguity issues. Thus, if you must start a promise on a background queue, you need to do something like this:
Promise { seal in DispatchQueue.global().async { seal(value) } }.done { value in //… }Or more simply (though with caveats; see the documentation for
wait):DispatchQueue.global().async(.promise) { return try fetch().wait() }.done { value in //… }However, you shouldn't need to do this often. If you find yourself wanting to use this technique, perhaps you should instead modify the code for
fetchto make it do its work on a background thread.
I wasn't sure of the exact issue behind this caution, so I spent some time trying to reproduce it, without much luck. Is it possible that current compilers handle this situation more smoothly?
E.g., this seems to work fine:
DispatchQueue.global().async(.promise) {
return Promise.value(42)
}.then {$0}.done { value in
print(value)
}.catch { _ in }
If the situation is in fact better now, it might be nice if the async(.promise) family provided its own unwrapping when the return type of the closure was a Promise or Guarantee so that, e.g., the return type of
queue.async(.promise) { Promise.value(42) }
would be Promise<Int> rather than Promise<Promise<Int>>.
It's potentially a breaking change, but since the docs have historically warned away from this, maybe not a big deal for PMK7?
I imagine a multiple line attempt would be ambiguous, but possibly not (hopefully not).
In general one must do multiple line attempts since one liners are inferred differently (and more leniently).