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] <mailto:[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/ 
> <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] 
>> <mailto:[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] 
>> <mailto:[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] 
>>> <mailto:[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] 
>>>> <mailto:[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] <mailto:[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] 
>>>>> <mailto:[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] <mailto:[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] <mailto:[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] 
>>>>>>> <mailto:[email protected]>> wrote:
>>>>>>> 
>>>>>>>> On Aug 25, 2017, at 12:34 AM, Howard Lovatt <[email protected] 
>>>>>>>> <mailto:[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] <mailto:[email protected]>
>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>> 
>>>>> --
>>>>> -- Howard.
>>>>> _______________________________________________
>>>>> swift-evolution mailing list
>>>>> [email protected] <mailto:[email protected]>
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>> 
> 
> _______________________________________________
> swift-evolution mailing list
> [email protected] <mailto:[email protected]>
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> <https://lists.swift.org/mailman/listinfo/swift-evolution>

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to