On 30.08.2017 3:43, Howard Lovatt wrote:
@Vladimir,

Default values are a problem for await/async when combined with parallel running because await returns a value and not an optional (unlike future's get). Below is a more realistic code for parallel running and a default value using async/await:

Thank you for the reply. Seems I'm missing something important, but

async render(image: await image, text: await text)

, as I understand currently, should NOT block the execution, execution will back here when image&text are 'ready', while

render(image: image.get ?? defaultImage, text: text.get ?? defaultText)

should block on .get(). No? This is why I asked if we need some 'sync' modifier 
like

sync preprocessImage(someImage)
, if we need to call func declared as async synchronously.

Vladimir.


    func updateImage() async {

        let image: Image

        async do { // Runs in parallel (async)

            image = try async preprocessImage(downloadImage())

        } catch {

            image = defaultImage

        }

        let text: String

        async do { // Runs in parallel (async)

            text = try async translate(downloadText())

        } catch {

            text = defaultText

        }
        // This line is complicated! We want render not to block (async), but 
have to
        await for image and text.
        // Render does not throw because it always has valid input.
// If async were allowed to prevent blocking then await could not
        async render(image: await image, text: await text)

    }


Which I don't think reads as well as the Future version:

    func updateImage() -> Future<Void> {

        return AsynchronousFuture { _ -> Void in

            let image = preprocessImage(downloadImage()) // Parallel, Futures 
are
            queued on creation

            let text = translate(downloadText()) // Parallel, Futures are 
queued on
            creation

            // Does not block (Futures are queued on creation), but has to wait 
for
            its inputs (get).

            render(image: image.get ?? defaultImage, text: text.get ?? 
defaultText)

        }

    }


In addition the async/await version does not have timeout; unlike the Future 
version.

Suppose that downloadImage doesn't fail, it just takes forever to download the image. The Future version will timeout automatically and the default image will be used. With async/await the code for downloadImage and downloadText will have to start timers and throw if the timers timeout. Nothing to do in the Future version, it handles timeout for you.

Neither or the above versions have cancel or control over the queue they execute on, but both would be much easier to add to the Future version, like timeout is much easier to add, since Futures support cancel and queue control directly.

   -- Howard.

On 30 August 2017 at 02:45, Vladimir.S via swift-evolution <[email protected] <mailto:[email protected]>> wrote:

    On 29.08.2017 19:02, Wallacy via swift-evolution wrote:

        In this example i think we lose clarity, just looking for the code we 
cant
        know if this two line will run on parallel or not!
        Also, image.get blocks the thread, in this case we need the await 
anyway! And
        `async` can throws too... So the error handler can be pretty similar.

        let  image=  asyncpreprocessImage(downloadImage()) // These first two 
lines
        run in parallel and I can "see" the async keyword.
        let  text=  asynctranslate(downloadText())
        await render(image: image ?? defaultImage,text: text ?? defaultText) // 
No
        blocking!


    FWIW: I'm following the whole discussion from the start, and do support the
    opinion that async/await is much clear solution that proposed Futures, 
especially
    for beginners.
    We need a low-level building blocks which can be used to implement
    Futures/Promises in libraries.
    Also I really like the idea of 'async' on the caller side to have code 
running in
    parallel.

    The 'async' version of func declaration is clearly saying what type it 
*want* to
    return, and 'async' modifier just saying *how* it will/can return that
    type('Image' in examples). So on both sides, on declaration and on caller 
side,
    we are clear what types we are working with.
    Future<Type> - is mixing of what is returning and how this will be 
returned. Code
    is saying that we preprocessesImage, but actually we have Future<Image> 
type, no
    'markers' of asynchronous code.

    Also, I wonder(if I missed that in proposal/discussion, please let me 
know), if I
    have async function like

    func foo() async -> Type {}

    , may I want to call it synchronously? If so, what would be a solution 
here? I
    can think about something like 'sync' modifier on caller side:
    let x = sync foo() // calling asynchronous function synchronously

    I believe that is what Future.get is doing, no?
    let future =  ...
    future.get() // blocks the execution, waits for the result.

    Probably it is reasonable to allow just call foo() to get blocking result, 
just
    like any other 'simple' blocking funcs that we call, but this can lead to
    unexpected behavior as user can expect async execution.

    With Futures, it seems like we can't "just" call such function and need to 
call
    .get() later:
    let future = someFuncReturnsFuture() // already returns Future<Type> type

    Vladimir.


        Like i said before! Today's, the proposal only lack two things over the
        `Future`....
        Parallel computing: Can be implemented by a third party library or a 
personal
        one, but i don't think this is a good approach to the first version.
        Coordination: This we can wait! And why? Because coordination, can be 
made in
        different ways, maybe is more suitable to a standard library 
class/function,
        not a language level resource.

        Also, coordination cant be applied to all variants of the runtimes in 
the
        same way! async/await as language level  works just as well with GCD as 
with
        pthreads or another API. And coordination is a compromise that we can 
make
        after that one.

        Em ter, 29 de ago de 2017 às 05:23, Howard Lovatt via swift-evolution
        <[email protected] <mailto:[email protected]>
        <mailto:[email protected] <mailto:[email protected]>>> 
escreveu:

             @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] <mailto:[email protected]>
        <mailto:[email protected] <mailto:[email protected]>>> 
wrote:


                     On 29 Aug 2017, at 02:22, Xiaodi Wu via swift-evolution
                     <[email protected] 
<mailto:[email protected]>
            <mailto:[email protected] 
<mailto:[email protected]>>> wrote:

                     On Mon, Aug 28, 2017 at 16:10 Adam Kemp via swift-evolution
                     <[email protected] 
<mailto:[email protected]>
            <mailto:[email protected] 
<mailto:[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())
                 awaitrender(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) })
                 awaitrender(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]
                <mailto:[email protected]>
                             <mailto:[email protected] 
<mailto:[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] <mailto:[email protected]>
                             <mailto:[email protected]
                <mailto:[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] <mailto:[email protected]>
                                     <mailto:[email protected]
                    <mailto:[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]>
                    <mailto:[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]>
                        <mailto:[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]>
                                             <mailto:[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]>
                            <mailto:[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= awaitloadWebResource("dataprofile.txt") let imageResource= awaitloadWebResource("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]>
                                                     <mailto:[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]>
<mailto:[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]>
<mailto:[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]>
<mailto:[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]>
<mailto:[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]>
                                            <mailto:[email protected]
                                            <mailto:[email protected]>>> wrote:


                                                                                
 On
                                                Aug 25, 2017, at 12:34 AM, 
Howard
Lovatt <[email protected]
                                                <mailto:[email protected]>
<mailto:[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]>
<mailto:[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]>
<mailto:[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]>
                    <mailto:[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]>
            <mailto:[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]>
            <mailto:[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]>
        <mailto:[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]>
        <mailto:[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] <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