Replies: 21 comments
-
Related: chaining syntaxes in #827 |
Beta Was this translation helpful? Give feedback.
-
I really missing uniform syntax for monad-like computations like Haskell, Scala, F# and others have. 😿 |
Beta Was this translation helpful? Give feedback.
-
Abusing LINQ doesn't count. |
Beta Was this translation helpful? Give feedback.
-
👍 for some syntactic sugar to make chaining tasks nicer. |
Beta Was this translation helpful? Give feedback.
-
Will |
Beta Was this translation helpful? Give feedback.
-
@Thaina That's part of why I'm unsure about the suggested syntax, but the language team can decide whether or not it could create issues. |
Beta Was this translation helpful? Give feedback.
-
Related: #74 var addresses = await context.GetOrderAsync(id: 5)
|> CustomerAsync()
|> AddressesAsync()
|> FirstOrDefault(); or simpler (depending on chosen syntax): var addresses = await context.GetOrderAsync(id: 5)
|> CustomerAsync
|> AddressesAsync
|> FirstOrDefault; |
Beta Was this translation helpful? Give feedback.
-
@Thaina There may be an issue with its use changing in different contexts However, conceptually they are similar
So Likewise I'm suggesting it combines task-like dereferencing/awaiting (obtaining its value) and member access.
|
Beta Was this translation helpful? Give feedback.
-
@mharasimowicz |
Beta Was this translation helpful? Give feedback.
-
The main thing that makes me uncomfortable with this proposal is the use of the |
Beta Was this translation helpful? Give feedback.
-
:sadpanda: I guess it would have to be this then; in which case is only one syntax var addresses = context.GetOrderAsync(id: 5).ConfigureAwait(false)
->CustomerAsync().ConfigureAwait(false)
->AddressesAsync().ConfigureAwait(false)
->FirstOrDefault(); |
Beta Was this translation helpful? Give feedback.
-
@benaadams You can also take the approach of setting the current synchronization context to null, or use a synchronization context which always executes on a particular task scheduler. |
Beta Was this translation helpful? Give feedback.
-
What about the following syntax?
Note:
The above is equivalent to:
|
Beta Was this translation helpful? Give feedback.
-
var firstAddress = (await GetCustomerAsync(id))
.Do(async x => (await GetAddressesAsync(x))
.Do(x => x.FirstOrDefault()); Where |
Beta Was this translation helpful? Give feedback.
-
@dadhi plus overloads for |
Beta Was this translation helpful? Give feedback.
-
@yaakov-h yep. whatever you need. I am using such extensions in couple of code-bases already, including big enterprise production. Given it such a small thing - it may simplify a lot. Especially together with LINQ methods. Often producing clean expression-bodied one-line methods at the end. Considering performance affected by lambda creation and usage, some of it may be mitigated by passing method group directly or using local method. I think inclusion of static / lightweight delegates in language should help a lot in this and other scenarios. |
Beta Was this translation helpful? Give feedback.
-
See also the discussion in #35 |
Beta Was this translation helpful? Give feedback.
-
What is the state of this proposal any chance of it being implemente in the next C# version? |
Beta Was this translation helpful? Give feedback.
-
Bold opinion: I think that the Task API as it exists today is likely not the Task API of the future, so I would caution against tightly coupling syntactic sugar to it. As an example of a more powerful task API, see Scala's zio, which guarantees resource finalization at the moment the task is complete or canceled or thrown from, and provides the "chain of reasoning" for what task should have "continued with next" had the task not been canceled or thrown from. The current Task API has a lot of FAQs about how to use it correctly, which mostly boil down to "async all the way" as the best practice. Keep in mind, from a historical perspective, in 2007, researchers were beginning to socialize the concept that a confluence of Power wall, ILP wall and slow clock frequency growth would combine to force new programming paradigms.
Even in early 2006, UC Berkeley computer scientists wrote a spate of papers articulating various solutions to the "coming crisis", including "The Problem with Threads". Charles Leierson and his group at Intel had developed the concept of work + span for modeling the cost of Amdahl's Law when decomposing computations represented as directed acyclic graphs into work-stealing dequeues. And the Task API emerged around that time, with the Parallel.ForEach and until George Chrysanthakopoulos work at Microsoft in 2008 on the Concurrency and Coordination Runtime, MSBuild was basically a single-threaded build engine. So, we're at best about 14 years into the development of "Task APIs", but really 2008 was the watershed year where Microsoft kicked us in the butt and said, "START WRITING MULTICORE PROGRAMS". I would guess that the next 14 years yield another two function steps improvement by focusing on debuggability and resource reasoning. The JVM world has already started to move on by some adapting CatsEffects and zio to model computations and solve these problems. .NET is a function step behind and still has this dreaded SynchronizationContext ambient value that changes depending on where you call your code from, rather than letting the caller say this is a pure unit of io, but the input comes from this impure source, and the output goes to this impure source. |
Beta Was this translation helpful? Give feedback.
-
@Timo-Weike Meanwhile in a macros world it is a one-liner define operator.($x, awaited) => (await($x)); Here is the discussion. |
Beta Was this translation helpful? Give feedback.
-
That's a good example of why I would generally be against macros in the language. |
Beta Was this translation helpful? Give feedback.
-
async deference operator
Current
await on results:
Or
Suggested
->
=>await
+.ConfigureAwait(false)
@.
=>await
Considerations
nullables?
->?
,@?.
Beta Was this translation helpful? Give feedback.
All reactions