Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: An await operator similar to ?. #4714

Closed
aL3891 opened this issue Aug 21, 2015 · 13 comments
Closed

Proposal: An await operator similar to ?. #4714

aL3891 opened this issue Aug 21, 2015 · 13 comments

Comments

@aL3891
Copy link

aL3891 commented Aug 21, 2015

Hi there,
Alot of times, especially when doing http requests with HttpClient, you have one async operation that is closely tied to another async operation. for example making a webrequest and then downloading the response. This can result on code that looks like this:

string result = await (await client.GetAsync("http://microsoft.com")).Content.ReadAsStringAsync();

However wouldn't it be nice if the language supported doing something like

string result = await client.GetAsync("http://microsoft.com")>.Content.ReadAsStringAsync();

Note that the >. is just something i pulled out of my hat, but the point is to have a "dot" operator that actually awaits and returns the result. I know i could just make a specific extension method that awaits the first call and then returns the second task like this

public async static Task<string> ReadString(this Task<HttpResponseMessage> res) => 
   await (await res).Content.ReadAsStringAsync();

but having this in the language and generalized would be neat

What do you think?

@aL3891 aL3891 changed the title An await operator similar to .? Proposal: An await operator similar to .? Aug 21, 2015
@dsaf
Copy link

dsaf commented Aug 21, 2015

@aL3891
Copy link
Author

aL3891 commented Aug 21, 2015

I'm no f# expert so i'm not quite sure about the exact semantics of the pipe operator, but from my casual understanding, yes (at least partially) :)

In my head I map it to the way extensions methods are expanded, so like how someList.Any() is translated to Enumerable.Any(someList), httpClient.GetAsync("")>.Content would be translated to (await httpClient.GetAsync("")).Content

@svick
Copy link
Contributor

svick commented Aug 22, 2015

I'm conflicted about something like this. While I agree that chaining awaits is currently inconvenient, I feel like what you're proposing is a bit too convenient. awaiting something is a "big" action, is affects what the code does in a significant way. I'm not sure making awaits easily overlooked is the right approach.

Maybe there could be some middle ground that keeps the await obvious, while making the syntax more convenient that it currently is?

@whoisj
Copy link

whoisj commented Aug 22, 2015

I like the idea, though it is generally good practice to not chain too many method call together, as it can make debugging more difficult later.

I do wonder if this wouldn't open up options for an analyzing, optimizing compiler to make additional optimizations because it could better understand intent...

Like a an async version of F#'s pipe operator?

Yeah, like that. I think I prefer that operator as well.

@aL3891
Copy link
Author

aL3891 commented Aug 22, 2015

I suppose its a matter of preference but i find intermediate variables like that a little distracting :) maybe it's because of the expression bodied member support but i feel like expressions are something we'll use more and more. That said i also sometimes split call chains up for debugging purposes, all though i do that less and less with the improvements to the VS debugger such a pinning

I'm not necessarily saying the await operator is bad, in fact i still see it as the best syntax for the "last" await in the call chain, it's just those middle ones that could be prettier.

Maybe it doesn't have to be something as innocuous as ">.", having a pipe character in there like in f# would make it more distinct from a regular member access.

@aL3891
Copy link
Author

aL3891 commented Aug 22, 2015

Or hey, how about this:

 awaitall client.GetAsync("http://microsoft.com").Content.ReadAsStringAsync();

Where the awaitall automatically awaits all the awaitables in the expression.
In a sense this is even more "magic" than an awaiting access operator, but in a sense it's more explicit as well, at least what the intention of the expression is. I do have a gut feeling this could open up for some weird edge cases though :P

@Dessix
Copy link

Dessix commented Aug 22, 2015

@aL3891 that could become confusing very fast in generic code that returns tasks or observables.

@RichiCoder1
Copy link

Agreed.

@aL3891
Copy link
Author

aL3891 commented Aug 24, 2015

yeah, just throwing it out there, some sort of access operator that awaits is probably better

@aL3891 aL3891 changed the title Proposal: An await operator similar to .? Proposal: An await operator similar to ?. Aug 26, 2015
@aluanhaddad
Copy link

@aL3891 you may want to take a look at #5445. I believe it covers these use cases.

@alrz
Copy link
Member

alrz commented Oct 31, 2015

Actually, as @aluanhaddad said, with help of #5444, and type inference, the example in the original post could be written as

string result = await client.GetAsync("http://microsoft.com")
                |> await ::Content.ReadAsStringAsync();

@aL3891
Copy link
Author

aL3891 commented Oct 31, 2015

Ah, neat!
Yes those two would cover this case, at least how i imagined it.

@gafter
Copy link
Member

gafter commented Mar 20, 2017

We are now taking language feature discussion on https://github.com/dotnet/csharplang for C# specific issues, https://github.com/dotnet/vblang for VB-specific features, and https://github.com/dotnet/csharplang for features that affect both languages.

See also dotnet/csharplang#35 for a proposal under consideration.

@gafter gafter closed this as completed Mar 20, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants