I can see where you're going with that.
For me, the big unknown (and unspecified so far) is
func process() async -> Image { ... }
let result = process() // what is result? CoroutineType<Image> ?
or am I missing something here?
On 28 août 2017 16:07 -0400, Adam Kemp <[email protected]>, wrote:
> I think the biggest tradeoff is clearer when you look at the examples from
> the proposal where futures are built on top of async/await:
>
> > func processImageData1a() async -> Image {
> > let dataResource = Future { await loadWebResource("dataprofile.txt") }
> > let imageResource = Future { await loadWebResource("imagedata.dat") }
> >
> > // ... other stuff can go here to cover load latency...
> >
> > let imageTmp = await decodeImage(dataResource.get(),
> > imageResource.get())
> > let imageResult = await dewarpAndCleanupImage(imageTmp)
> > return imageResult
> > }
>
> With this approach you have to wrap each call site to create a future.
> Compare to this:
>
> > func processImageData1a() -> Future<Image> {
> > let dataResourceFuture = loadWebResource("dataprofile.txt”);
> > let imageResourceFuture = loadWebResource("imagedata.dat”);
> >
> > // ... other stuff can go here to cover load latency...
> >
> > let imageTmp = await decodeImage(await dataResourceFuture, await
> > imageResourceFuture)
> > let imageResult = await dewarpAndCleanupImage(imageTmp)
> > return imageResult
> > }
>
> Here, not only are the explicit wrappers gone, but this function itself can
> be used with either await or as a future. You get both options with one
> implementation.
>
> As I’ve mentioned before, C#’s implementation is not tied to any one
> particular futures implementation. The Task type is commonly used, but
> async/await does not directly depend on Task. Instead it works with any
> return type that meets certain requirements (detailed here:
> https://blogs.msdn.microsoft.com/pfxteam/2011/01/13/await-anything/). Swift
> could do this using a protocol, which can be retroactively applied using an
> extension.
>
> Obviously for this to be useful we would need some kind of existing future
> implementation, but at least we wouldn’t be tied to any particular one. That
> would mean library maintainers who have already been using their own futures
> implementations could quickly adopt async/await in their code without having
> to rewrite their futures library or throw wrappers around every usage of
> async/await. They could just adopt a protocol (using an extension, even) and
> get async/await support for free.
>
> The downside is that this feature would be specific to the async/await use
> case rather than a generic coroutine implementation (i.e., there would have
> to be a separate compiler transform for yield return). It’s not clear to me
> why it should be a goal to have just one generic coroutine feature. The
> real-world usages of async/await and yield return are different enough that
> I’m not convinced we could have a single compiler feature that meets the
> needs of both cleanly.
>
> > On Aug 27, 2017, at 7:35 PM, Florent Vilmart <[email protected]> wrote:
> >
> > Adam, you’re completely right, languages as c# and JS have been through the
> > path before, (callback, Promises , async/await) I believe Chris’s goal it
> > to avoid building a promise implementation and go straight to a coroutines
> > model, which is more deeply integrated with the compiler. I don’t see a
> > particular trade off, pursuing that route, and the main benefit is that
> > coroutines can power any asynchronous metaphor (Signals, Streams, Futures,
> > Promises etc...) which is not true of Futures so i would tend to think that
> > for the long run, and to maximize usability, async/await/yield would
> > probably be the way to go.
> >
> > On Aug 27, 2017, 22:22 -0400, Adam Kemp <[email protected]>, wrote:
> > > As has been explained, futures can be built on top of async/await (or the
> > > other way around). You can have the best of both worlds. We are not
> > > losing anything by having this feature. It would be a huge improvement to
> > > have this as an option.
> > >
> > > However, using futures correctly requires more nested closures than you
> > > have shown in your examples to avoid blocking any threads. That's why
> > > you're not seeing the advantage to async/await. You're comparing examples
> > > that have very different behaviors.
> > >
> > > That said, I have also expressed my opinion that it is better to build
> > > async/await on top of futures rather than the other way around. I believe
> > > it is more powerful and cleaner to make async/await work with any
> > > arbitrary future type (via a protocol). The alternative (building futures
> > > on top of async/await) requires more code when the two are mixed. I very
> > > much prefer how it's done in C#, where you can freely mix the two models
> > > without having to resort to ad-hoc wrappers, and you can use async/await
> > > with any futures implementation you might already be using.
> > >
> > > I really think we should be having more discussion about the tradeoffs
> > > between those two approaches, and I'm concerned that some of the opinions
> > > about how C# does it are not based on a clear and accurate understanding
> > > of how it actually works in that language.
> > >
> > > --
> > > Adam Kemp
> > >
> > > On Aug 27, 2017, at 6:02 PM, Howard Lovatt <[email protected]>
> > > wrote:
> > >
> > > > The async/await is very similar to the proposed Future (as I posed
> > > > earlier) with regard to completion-handler code, they both re-write the
> > > > imported completion-handler function using a closure, the relevant
> > > > sentence from the Async Proposal is:
> > > >
> > > > > "Under the hood, the compiler rewrites this code using nested
> > > > > closures ..."
> > > >
> > > > Unlike the proposed future code the async code is not naturally
> > > > parallel, in the running example the following lines from the async
> > > > code are run in series, i.e. await blocks:
> > > >
> > > > let dataResource = await loadWebResource("dataprofile.txt")
> > > > let imageResource = await loadWebResource("imagedata.dat")
> > > > The equivalent lines using the proposed Future:
> > > > let dataResource = loadWebResource("dataprofile.txt")
> > > > let imageResource = loadWebResource("imagedata.dat")
> > > > Run in parallel and therefore are potentially faster assuming that
> > > > resources, like cores and IO, are available.
> > > >
> > > > Therefore you would be better using a Future than an async, so why
> > > > provide an async unless you can make a convincing argument that it
> > > > allows you to write a better future?
> > > >
> > > > -- Howard.
> > > >
> > > > > On 28 August 2017 at 09:59, Adam Kemp <[email protected]> wrote:
> > > > > > This example still has nested closures (to create a Future), and
> > > > > > still relies on a synchronous get method that will block a thread.
> > > > > > Async/await does not require blocking any threads.
> > > > > >
> > > > > > I’m definitely a fan of futures, but this example isn’t even a good
> > > > > > example of using futures. If you’re using a synchronous get method
> > > > > > then you’re not using futures properly. They’re supposed to make it
> > > > > > easy to avoid writing blocking code. This example just does the
> > > > > > blocking call on some other thread.
> > > > > >
> > > > > > Doing it properly would show the benefits of async/await because it
> > > > > > would require more nesting and more complex error handling. By
> > > > > > simplifying the code you’ve made a comparison between proper
> > > > > > asynchronous code (with async/await) and improper asynchronous code
> > > > > > (your example).
> > > > > >
> > > > > > That tendency to want to just block a thread to make it easier is
> > > > > > exactly why async/await is so valuable. You get simple code while
> > > > > > still doing it correctly.
> > > > > >
> > > > > > --
> > > > > > Adam Kemp
> > > > > >
> > > > > > On Aug 27, 2017, at 4:00 PM, Howard Lovatt via swift-evolution
> > > > > > <[email protected]> wrote:
> > > > > >
> > > > > > > The running example used in the white paper coded using a Future
> > > > > > > is:
> > > > > > >
> > > > > > > func processImageData1() -> Future<Image> {
> > > > > > > return AsynchronousFuture { _ -> Image in
> > > > > > > let dataResource = loadWebResource("dataprofile.txt") //
> > > > > > > dataResource and imageResource run in parallel.
> > > > > > > let imageResource = loadWebResource("imagedata.dat")
> > > > > > > let imageTmp = decodeImage(dataResource.get ??
> > > > > > > Resource(path: "Default data resource or prompt user"),
> > > > > > > imageResource.get ?? Resource(path: "Default image resource or
> > > > > > > prompt user"))
> > > > > > > let imageResult = dewarpAndCleanupImage(imageTmp.get
> > > > > > > ?? Image(dataPath: "Default image or prompt user", imagePath:
> > > > > > > "Default image or prompt user"))
> > > > > > > return imageResult.get ?? Image(dataPath: "Default image
> > > > > > > or prompt user", imagePath: "Default image or prompt user")
> > > > > > > }
> > > > > > > }
> > > > > > >
> > > > > > > This also avoids the pyramid of doom; the pyramid is avoided by
> > > > > > > converting continuation-handlers into either a sync or future,
> > > > > > > i.e. it is the importer that eliminates the nesting by
> > > > > > > translating the code automatically.
> > > > > > >
> > > > > > > This example using Future also demonstrates three advantages of
> > > > > > > Future: they are naturally parallel (dataResource and
> > > > > > > imageResource lines run in parallel), they timeout automatically
> > > > > > > (get returns nil if the Future has taken too long), and if there
> > > > > > > is a failure (for any reason including timeout) it provides a
> > > > > > > method of either detecting the failure or providing a default
> > > > > > > (get returns nil on failure).
> > > > > > >
> > > > > > > There are a three of other advantages a Future has that this
> > > > > > > example doesn’t show: control over which thread the Future runs
> > > > > > > on, Futures can be cancelled, and debugging information is
> > > > > > > available.
> > > > > > >
> > > > > > > You could imagine `async` as a syntax sugar for Future, e.g. the
> > > > > > > above Future example could be:
> > > > > > >
> > > > > > > func processImageData1() async -> Image {
> > > > > > > let dataResource = loadWebResource("dataprofile.txt") //
> > > > > > > dataResource and imageResource run in parallel.
> > > > > > > let imageResource = loadWebResource("imagedata.dat")
> > > > > > > let imageTmp = decodeImage(dataResource.get ??
> > > > > > > Resource(path: "Default data resource or prompt user"),
> > > > > > > imageResource.get ?? Resource(path: "Default image resource or
> > > > > > > prompt user"))
> > > > > > > let imageResult = dewarpAndCleanupImage(imageTmp.get ??
> > > > > > > Image(dataPath: "Default image or prompt user", imagePath:
> > > > > > > "Default image or prompt user"))
> > > > > > > return imageResult.get ?? Image(dataPath: "Default image or
> > > > > > > prompt user", imagePath: "Default image or prompt user")
> > > > > > > }
> > > > > > >
> > > > > > > Since an async is sugar for Future the async runs as soon as it
> > > > > > > is created (as soon as the underlying Future is created) and get
> > > > > > > returns an optional (also cancel and status would be still be
> > > > > > > present). Then if you want control over threads and timeout they
> > > > > > > could be arguments to async:
> > > > > > >
> > > > > > > func processImageData1() async(queue: DispatchQueue.main,
> > > > > > > timeout: .seconds(5)) -> Image { ... }
> > > > > > >
> > > > > > > > On Sat, 26 Aug 2017 at 11:00 pm, Florent Vilmart
> > > > > > > > <[email protected]> wrote:
> > > > > > > > > Howard, with async / await, the code is flat and you don’t
> > > > > > > > > have to unowned/weak self to prevent hideous cycles in the
> > > > > > > > > callbacks.
> > > > > > > > > Futures can’t do that
> > > > > > > > >
> > > > > > > > > On Aug 26, 2017, 04:37 -0400, Goffredo Marocchi via
> > > > > > > > > swift-evolution <[email protected]>, wrote:
> > > > > > > > > > With both he now built in promises in Node8 as well as
> > > > > > > > > > libraries like Bluebird there was ample time to evaluate
> > > > > > > > > > them and convert/auto convert at times libraries that loved
> > > > > > > > > > callback pyramids of doom when the flow grows complex into
> > > > > > > > > > promise based chains. Converting to Promises seems magical
> > > > > > > > > > for the simple case, but can quickly descend in hard to
> > > > > > > > > > follow flows and hard to debug errors when you move to non
> > > > > > > > > > trivial multi path scenarios. JS is now solving it with
> > > > > > > > > > their implementation of async/await, but the point is that
> > > > > > > > > > without the full picture any single solution would break
> > > > > > > > > > horribly in real life scenarios.
> > > > > > > > > >
> > > > > > > > > > Sent from my iPhone
> > > > > > > > > >
> > > > > > > > > > On 26 Aug 2017, at 06:27, Howard Lovatt via swift-evolution
> > > > > > > > > > <[email protected]> wrote:
> > > > > > > > > >
> > > > > > > > > > > My argument goes like this:
> > > > > > > > > > >
> > > > > > > > > > > 1. You don't need async/await to write a powerful
> > > > > > > > > > > future type; you can use the underlying threads just as
> > > > > > > > > > > well, i.e. future with async/await is no better than
> > > > > > > > > > > future without.
> > > > > > > > > > >
> > > > > > > > > > > 2. Since future is more powerful, thread control,
> > > > > > > > > > > cancel, and timeout, people should be encouraged to use
> > > > > > > > > > > this; instead because async/await are language features
> > > > > > > > > > > they will be presumed, incorrectly, to be the best way,
> > > > > > > > > > > consequently people will get into trouble with deadlocks
> > > > > > > > > > > because they don't have control.
> > > > > > > > > > >
> > > > > > > > > > > 3. async/await will require some engineering work and
> > > > > > > > > > > will at best make a mild syntax improvement and at worst
> > > > > > > > > > > lead to deadlocks, therefore they just don't carry their
> > > > > > > > > > > weight in terms of useful additions to Swift.
> > > > > > > > > > >
> > > > > > > > > > > Therefore, save some engineering effort and just provide
> > > > > > > > > > > a future library.
> > > > > > > > > > >
> > > > > > > > > > > To turn the question round another way, in two forms:
> > > > > > > > > > >
> > > > > > > > > > > 1. What can async/wait do that a future can't?
> > > > > > > > > > >
> > > > > > > > > > > 2. How will future be improved if async/await is added?
> > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > > -- Howard.
> > > > > > > > > > >
> > > > > > > > > > > > On 26 August 2017 at 02:23, Joe Groff
> > > > > > > > > > > > <[email protected]> wrote:
> > > > > > > > > > > > >
> > > > > > > > > > > > > > On Aug 25, 2017, at 12:34 AM, Howard Lovatt
> > > > > > > > > > > > > > <[email protected]> wrote:
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > In particular a future that is cancellable is more
> > > > > > > > > > > > > > powerful that the proposed async/await.
> > > > > > > > > > > > >
> > > > > > > > > > > > > It's not more powerful; the features are to some
> > > > > > > > > > > > > degree disjoint. You can build a Future abstraction
> > > > > > > > > > > > > and then use async/await to sugar code that threads
> > > > > > > > > > > > > computation through futures. Getting back to Jakob's
> > > > > > > > > > > > > example, someone (maybe the Clang importer, maybe
> > > > > > > > > > > > > Apple's framework developers in an overlay) will
> > > > > > > > > > > > > still need to build infrastructure on top of
> > > > > > > > > > > > > IBActions and other currently ad-hoc signalling
> > > > > > > > > > > > > mechanisms to integrate them into a more expressive
> > > > > > > > > > > > > coordination framework.
> > > > > > > > > > > > >
> > > > > > > > > > > > > -Joe
> > > > > > > > > > >
> > > > > > > > > > > _______________________________________________
> > > > > > > > > > > swift-evolution mailing list
> > > > > > > > > > > [email protected]
> > > > > > > > > > > https://lists.swift.org/mailman/listinfo/swift-evolution
> > > > > > > --
> > > > > > > -- Howard.
> > > > > > > _______________________________________________
> > > > > > > swift-evolution mailing list
> > > > > > > [email protected]
> > > > > > > https://lists.swift.org/mailman/listinfo/swift-evolution
> > > >
>
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution