locked
Why not "await return" ?

    Question

  • hello guys :)

    for enumerables we have yeild return but for async we have return await. that is kinda inconsistent.. is there is a perticular reason for that?

    i'd much prefer having await return. it reads better too i think :)

    also, in the refresh i see you still have the async keyword in c# [instead of just inferring the 'async' from the use of an await inside the method and a return type of Task] how final is that decision?

    i think it would be better to mirror the IEnumerable syntax, both for consistacy and for readability :)

    just my 2c

    Wednesday, April 13, 2011 9:07 PM

Answers

  •  

    Q. Why do we have "return" rather than "await return" ?

    PRO for just "return": in both sync and async method, the return statement returns the result of the computation.

    PRO for just "return": when you're taking some sync code, and turning it async (which we believe will be a very common process), it's easier.

    PRO for "await return": it signals clearly that the type of the return operand is different from the declared return type of the function

    EQUAL for both: you should have some syntax to indicate that the return statement is doing something different. It might be that this different syntax is in the "async" modifier. Or it might be that it comes in the "await return" statement. Either will work.

    CON for "await return": you're not "awaiting a return". The phrase doesn't make sense. If anything it would have had to be "async return".

    In the end, we didn't find "async return" very compelling. It felt like the extra keyword there was just needless busy-work for people writing code.

     

    Q. Why use the "async" modifier, rather than inferring it ? How final is this decision ?

    PRO for "async" modifier: users need to have a conceptual model for this new kind of function. They will mentally ascribe a name to it. That name should be "async method". If we put this terminology right there in the syntax, then the mind/code bridge becomes easier.

    PRO for inferring async: similarity to iterators.

    PRO for "async" modifier: well, if we were to do iterators again from scratch, we'd probably do them with an "iterator" modifier and just the keyword "yield" rather than the compound keyword "yield return"...

    PRO for "async" modifier: it allows us to use just the "await" keyword on its own, rather than a compound keyword "await return". (which would have been needed otherwise to avoid back-compat breaks for people who have identifiers or types named "await").

    PRO for "async" modifier: more opportunities for intellisense, error messages & other opportunities to teach users about the feature.

    We went backwards and forwards on this for a long time. In the end, the strength of just the simple keyword "await" was very compelling, and also it gave developers a warm fuzzy feeling inside to see the "async" keyword, and also we appreciated the intellisense+IDE possibilities (none of which, I'm afraid, are present in the CTP).

    If there's a really strong outcry against the "async" modifier at this stage then we'd reconsider it. But we haven't seen that kind of outcry.

     

    Thursday, April 14, 2011 3:38 AM
    Owner
  • Ah, I see. That video shows code like the following:

    async Task<Movie[]> GetMovies()
    {
       return await TaskEx.Run(...);
    }

    The "return await" isn't any special. I could rewrite it like this:

    async Task<Movie[]> GetMovies()
    {
       var t = TaskEx.Run(...);
       var r = await t;
       return r;
    }

    In other words:
    "await <expr>" is just a unary expression, like any other expression.
    "return <expr>" is just a statement, like any other statement.
    The "return" and "await" keywords aren't tied together.
    Async methods use a "return" statement on its own.

    Thank you for your feedback Allan! Is definitely appreciated.

     

    Thursday, April 14, 2011 9:00 PM
    Owner

All replies

  • I'm actually rather glad the syntax is different.  There's a big conceptual between iterators and await...

     

    With iterators, yield return is, at that point, effectively returning from the method and adding the value into the IEnumerable<T> you're implementing.  With IEnumerable<T> using deferred execution, this is effectively a return at that point, so "yield return value;" makes sense.

     

    With await, you're not returning a value.  Await is more of a "allow the main process to continue while I await this operation".  You can do things with await like combine two tasks and await their results, etc.   As such, its a very different mental model than iterators.  You're also not returning a value when you use await - you're just allowing the main program execution flow to continue.

     


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".
    Wednesday, April 13, 2011 11:38 PM
    Moderator
  •  

    Q. Why do we have "return" rather than "await return" ?

    PRO for just "return": in both sync and async method, the return statement returns the result of the computation.

    PRO for just "return": when you're taking some sync code, and turning it async (which we believe will be a very common process), it's easier.

    PRO for "await return": it signals clearly that the type of the return operand is different from the declared return type of the function

    EQUAL for both: you should have some syntax to indicate that the return statement is doing something different. It might be that this different syntax is in the "async" modifier. Or it might be that it comes in the "await return" statement. Either will work.

    CON for "await return": you're not "awaiting a return". The phrase doesn't make sense. If anything it would have had to be "async return".

    In the end, we didn't find "async return" very compelling. It felt like the extra keyword there was just needless busy-work for people writing code.

     

    Q. Why use the "async" modifier, rather than inferring it ? How final is this decision ?

    PRO for "async" modifier: users need to have a conceptual model for this new kind of function. They will mentally ascribe a name to it. That name should be "async method". If we put this terminology right there in the syntax, then the mind/code bridge becomes easier.

    PRO for inferring async: similarity to iterators.

    PRO for "async" modifier: well, if we were to do iterators again from scratch, we'd probably do them with an "iterator" modifier and just the keyword "yield" rather than the compound keyword "yield return"...

    PRO for "async" modifier: it allows us to use just the "await" keyword on its own, rather than a compound keyword "await return". (which would have been needed otherwise to avoid back-compat breaks for people who have identifiers or types named "await").

    PRO for "async" modifier: more opportunities for intellisense, error messages & other opportunities to teach users about the feature.

    We went backwards and forwards on this for a long time. In the end, the strength of just the simple keyword "await" was very compelling, and also it gave developers a warm fuzzy feeling inside to see the "async" keyword, and also we appreciated the intellisense+IDE possibilities (none of which, I'm afraid, are present in the CTP).

    If there's a really strong outcry against the "async" modifier at this stage then we'd reconsider it. But we haven't seen that kind of outcry.

     

    Thursday, April 14, 2011 3:38 AM
    Owner
  • I'm actually rather glad the syntax is different.  There's a big conceptual between iterators and await...

     With iterators, yield return is, at that point, effectively returning from the method and adding the value into the IEnumerable<T> you're implementing.  With IEnumerable<T> using deferred execution, this is effectively a return at that point, so "yield return value;" makes sense.

     With await, you're not returning a value.  Await is more of a "allow the main process to continue while I await this operation".  You can do things with await like combine two tasks and await their results, etc.   As such, its a very different mental model than iterators.  You're also not returning a value when you use await - you're just allowing the main program execution flow to continue.

     

    i strongly disagree.. first of all they are implemented in a very similar fashion [according to anders atleast, during pdc] also, you are wrong about await not beeing a point of return. thats exactly what it is.  a point where you return a Task of a value (or just a Task). you're still returning control to the caller, the compiler is just wrapping the rest of your method in a continuation

    Thursday, April 14, 2011 8:27 PM
  • my question was not "Why do we have "return" rather than "await return" ?", my question was, why do you have return await instead of await return

    your awnser is confusing to me though, are you saying its just 'return'? atleast in this video around ~5 minutes in they're using await return, but maybe im missing something.

    if its just return, thats great, if you can get away with not adding keywords thats good. this is also the reason why i dont like 'async'. its not needed in c# and the fact that its vb is not a good enough reason to add it to c# [mads gave language parity as a reason during pdc atleast]

    when you release some more tooling i might change my mind (kinda hard to take tooling youve never shown talked about or released into consideration ;) ) but as it is right now i find the async redundant and inconsistent with the iterators. im not sure that qualifies as an 'outcry' but you wanted feedback(right?) so im giving that.

    Thursday, April 14, 2011 8:51 PM
  • Ah, I see. That video shows code like the following:

    async Task<Movie[]> GetMovies()
    {
       return await TaskEx.Run(...);
    }

    The "return await" isn't any special. I could rewrite it like this:

    async Task<Movie[]> GetMovies()
    {
       var t = TaskEx.Run(...);
       var r = await t;
       return r;
    }

    In other words:
    "await <expr>" is just a unary expression, like any other expression.
    "return <expr>" is just a statement, like any other statement.
    The "return" and "await" keywords aren't tied together.
    Async methods use a "return" statement on its own.

    Thank you for your feedback Allan! Is definitely appreciated.

     

    Thursday, April 14, 2011 9:00 PM
    Owner
  • ah, i get it now, thanks :)

    still think you can do without 'async' though ;) but i'll wait for the tooling, the c# team havent shipped a bad language feature yet so im sure you guys will sort it out

    Thursday, April 14, 2011 9:04 PM