I understand. But it’s quite problematic to have to write all Future returning functions with Future inputs just to be able to support parallel computations. It’s not how futures are using in C# and JavaScript.
> On 30 Aug 2017, at 03:02, Howard Lovatt <[email protected]> wrote: > > @David, > > The signatures would be: > > func processImage(_ image: Future<Image>) -> Future<Image> > func translate(_ text: Future<String>) -> Future<Image> > > Inside `processImage` and `translate` you would `get` the values at the point > were needed so that downloadImage and downloadText run in parallel (which is > highly desirable). > > > -- Howard. > >> On 30 August 2017 at 07:21, David Hart <[email protected]> wrote: >> I don’t think the examples are 100% equivalent. In your version with the >> Future library, preprocessImage and translate need to accept futures as >> argument, correct? That’s more restrictive than in my example code where >> async/await specifically provide sugar over then. Plus I don’t understand >> why you mention that the Future version handles errors when async/await also >> plays very nicely with errors. >> >>> On 29 Aug 2017, at 10:22, Howard Lovatt <[email protected]> wrote: >>> >>> @David, >>> >>> Using the `Future` library based on GCD that I have previously posted your >>> example would be: >>> >>> let image = preprocessImage(downloadImage()) // These first two lines run >>> in parallel >>> let text = translate(downloadText()) >>> render(image: image.get ?? defaultImage, text: text.get ?? defaultText) >>> >>> The main difference, and I would argue an improvement, is that the `Future` >>> version handles errors. >>> >>> So what advantage does async/await have over a `Future` library we can >>> write today? >>> >>> >>> -- Howard. >>> >>>> On 29 August 2017 at 15:28, David Hart via swift-evolution >>>> <[email protected]> wrote: >>>> >>>>> On 29 Aug 2017, at 02:22, Xiaodi Wu via swift-evolution >>>>> <[email protected]> wrote: >>>>> >>>>>> On Mon, Aug 28, 2017 at 16:10 Adam Kemp via swift-evolution >>>>>> <[email protected]> wrote: >>>>>> I know what the proposal said. I’m making a case that there is value in >>>>>> doing it differently. >>>>>> >>>>>> The composability of futures is valuable. Mixing and matching >>>>>> async/await with futures is also valuable. The queue-returning behavior >>>>>> that you can get from futures is also valuable, and building async/await >>>>>> on top of futures means async/await can get that for free. >>>>> >>>>> Why couldn't you mix and match async/await and futures and get the >>>>> queue-return behavior of futures if futures are built on top of >>>>> async/await instead off the other way around? >>>> >>>> We could, but the syntax is much worse. Contrast: >>>> >>>> async/await built on top of Futures >>>> >>>> let image = preprocessImage(downloadImage()) >>>> let text = translate(downloadText()) >>>> await render(image: image, text: text) >>>> >>>> Futures built on top of async/await >>>> >>>> let image = Future(downloadImage).then({ preprocessImage($0) }) >>>> let text = Future(downloadText).then({ translate($0) }) >>>> await render(image: image.get(), text: text.get()) >>>> >>>>>> Maybe you don’t value those things, which is fine. But I do, and maybe >>>>>> other people do too. That’s why we’re having a discussion about it. >>>>>> >>>>>> It can also be valuable having a minimal implementation, but we have to >>>>>> acknowledge that it comes with a downside as well. The problem with >>>>>> doing a minimal implementation is that you can be stuck with the >>>>>> consequences for a long time. I want to make sure that we’re not stuck >>>>>> with the consequences of a minimal implementation that doesn’t >>>>>> adequately address the problems that async/await should be addressing. >>>>>> I’d hate for Swift to get an async/await that is so weak that it has to >>>>>> be augmented by tedious boilerplate code before it’s useful. >>>>>> >>>>>> >>>>>>> On Aug 28, 2017, at 1:54 PM, Wallacy <[email protected]> wrote: >>>>>>> >>>>>>> We don't need to this now! >>>>>>> >>>>>>> Again: (Using proposal words) >>>>>>> >>>>>>> "It is important to understand that this is proposing compiler support >>>>>>> that is completely concurrency runtime-agnostic. This proposal does not >>>>>>> include a new runtime model (like "actors") - it works just as well >>>>>>> with GCD as with pthreads or another API. Furthermore, unlike designs >>>>>>> in other languages, it is independent of specific coordination >>>>>>> mechanisms, such as futures or channels, allowing these to be built as >>>>>>> library feature" >>>>>>> >>>>>>> and >>>>>>> >>>>>>> "This proposal does not formally propose a Future type, or any other >>>>>>> coordination abstractions. There are many rational designs for futures, >>>>>>> and a lot of experience working with them. On the other hand, there are >>>>>>> also completely different coordination primitives that can be used with >>>>>>> this coroutine design, and incorporating them into this proposal only >>>>>>> makes it larger." >>>>>>> >>>>>>> and >>>>>>> >>>>>>> We focus on task-based concurrency abstractions commonly encountered in >>>>>>> client and server applications, particularly those that are highly >>>>>>> event driven (e.g. responding to UI events or requests from clients). >>>>>>> This does not attempt to be a comprehensive survey of all possible >>>>>>> options, nor does it attempt to solve all possible problems in the >>>>>>> space of concurrency. Instead, it outlines a single coherent design >>>>>>> thread that can be built over the span of years to incrementally drive >>>>>>> Swift to further greatness. >>>>>>> >>>>>>> and >>>>>>> >>>>>>> This proposal has been kept intentionally minimal, but there are many >>>>>>> possible ways to expand this in the future. >>>>>>> >>>>>>> .... >>>>>>> >>>>>>> The point is: No Future type is indeed proposed yet! >>>>>>> >>>>>>> The proposal try to include de "minimum" required to implement a basic >>>>>>> async/await to solve the problem created by the GCD! (Pyramid of doom) >>>>>>> >>>>>>> The question is: How do you do the same using dispatch_async ? >>>>>>> dispatch_async also does not return nothing to do what you are >>>>>>> intentend do do! >>>>>>> >>>>>>> Algo, by Swift 5 manifesto, there's no compromise to make a "complete" >>>>>>> concurrency model by this time! >>>>>>> >>>>>>> My intention is only make parity to dispatch_async, but also make the >>>>>>> ground free to make more complex implementation like Futures in another >>>>>>> round on top of this one. >>>>>>> >>>>>>> This 'async T' can be a real type in the future? Maybe will... But >>>>>>> doesn't matter now! Now we only need to is some kind of type which need >>>>>>> to be unwrapped using await before use. Maybe this intermediary/virtual >>>>>>> type can be a real thing and gain some abilities at some point! Maybe a >>>>>>> full Future type, why not? >>>>>>> >>>>>>>> Em seg, 28 de ago de 2017 às 17:33, Adam Kemp <[email protected]> >>>>>>>> escreveu: >>>>>>>> How would these anonymous types get composed? If I wanted to implement >>>>>>>> a function that takes a collection of futures and wait on it, how >>>>>>>> would I do that? That is, how would I implement the equivalent of C#’s >>>>>>>> Task.WhenAll and Task.WhenAny methods? >>>>>>>> >>>>>>>> More generally, how do you pass one of these typeless futures to some >>>>>>>> other function so that we can do the waiting there? >>>>>>>> >>>>>>>> >>>>>>>>> On Aug 28, 2017, at 1:23 PM, Wallacy <[email protected]> wrote: >>>>>>>>> >>>>>>>>> And that's why I (and others) are suggesting: >>>>>>>>> >>>>>>>>> func processImageData1a() async -> Image { >>>>>>>>> let dataResource = async loadWebResource("dataprofile.txt") // No >>>>>>>>> future type here... Just another way to call dispatch_async under the >>>>>>>>> hood. >>>>>>>>> let imageResource = async loadWebResource("imagedata.dat") >>>>>>>>> >>>>>>>>> // ... other stuff can go here to cover load latency... >>>>>>>>> >>>>>>>>> let imageTmp = await decodeImage(dataResource, imageResource) // >>>>>>>>> Compiles force await call here... >>>>>>>>> let imageResult = await dewarpAndCleanupImage(imageTmp) >>>>>>>>> return imageResult >>>>>>>>> } >>>>>>>>> >>>>>>>>> And now we gain all advantages of async/await again without to handle >>>>>>>>> with one more type. >>>>>>>>> >>>>>>>>>> Em seg, 28 de ago de 2017 às 17:07, Adam Kemp via swift-evolution >>>>>>>>>> <[email protected]> escreveu: >>>>>>>>>> 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 >>>>>>>> >>>>>> >>>>>> _______________________________________________ >>>>>> 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 >>>> >>>> >>>> _______________________________________________ >>>> 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
