My two cents
Dmitry Olshansky
dmitry.olsh at gmail.com
Tue Oct 24 05:40:06 UTC 2017
On Tuesday, 24 October 2017 at 04:26:42 UTC, Adam Wilson wrote:
> On 10/23/17 17:27, flamencofantasy wrote:
>> On Monday, 23 October 2017 at 22:22:55 UTC, Adam Wilson wrote:
>>> On 10/23/17 08:21, Kagamin wrote:
>>>> [...]
>>>
>>> Actually I think it fits perfectly with D, not for reason of
>>> performance, but for reason of flexibility. D is a polyglot
>>> language,
>>> with by far the most number of methodologies supported in a
>>> single
>>> language that I've ever encountered.
>>>
>>> [...]
>>
>> There is a lot of misunderstanding about async/await. It has
>> nothing to
>> do with "conservation of thread resources" or trading "raw
>> performance
>> for an ability
>>> to handle a truly massive number of simultaneous tasks".
>>> Async/await
>>> is just 'syntactic sugar' where the compiler re-writes your
>>> code into
>>> a state machine around APM (Asynchronous programming model
>>> which was
>>> introduced in .NET 2.0 sometime around 2002 I believe).
>>> That's all
>>> there is to it, it makes your asynchronous code look and feel
>>> synchronous.
>
>
> The only parts of Async/Await that have anything to do with APM
> are the interop stubs. C#'s Async/Await is built around the
> Task Asynchronous Programming model (e.g. Task and Task<T>) the
> compiler lowers to those, not APM. A common misunderstanding is
> that Task/Task<T> is based on APM, it's not, Task uses
> fundamentally different code underneath. On Linux/macOS it
> actually uses libuv (at the end of the day all of these
> programming models are callback based).
>
I’ll throw in my 2 rubbles.
I actually worked on a VM that has async/await feature built-in
(Dart language).
It is a plain syntax sugar for Future/Promise explicit asynchrony
where async automatically return Future[T] or Observable[T] (the
latter is async stream).
Async function with awaits is then re-written as a single
call-back with a basic state machine, each state corresponds to
the line where you did await.
Example:
async double calculateTax(){
double taxRate = await getTaxRates();
double income = await getIncome();
return taxRate * income;
}
Becomes roughly this (a bit more mechanical though):
Future!double calculateTax(){
int state = 0;
Promise!double __ret;
double taxRate;
double income;
void cb() {
if(state == 0) {
state = 1;
getTaxRates().andThen((double ret){
taxRate = ret;
cb();
});
}
else if (state == 1) {
state = 2;
getIncome().andThen((double ret){
income = ret;
cb();
});
else if (state == 2){
__ret.resolve(taxRate*income);
}
}
cb();
}
It doesn’t matter what mechanics you use to complete promises -
be it IO scheduler a-la libuv or something else. Async/await is
agnostic to that.
Still there is a fair amount of machinery to hide the rewrite
from the user and in particular print stack trace as if it was
normal sequential code.
> Yes, C#'s async design does make code look and feel
> synchronous, and it was intentionally designed that way, but
> that is not *why* they did Async. That misunderstanding arises
> from an interview that Anders did in which he was asked why
> they held Async back for three years after announcing it at
> PDC08. In that same talk Anders specifically says that the
> purpose of the Async is to free up threads to continue
> execution, his example is a Windows Desktop Message Pump and
> fetching pictures from the internet (long-wait IO), but the
> principal applies to any thread. They held back async for three
> years because they needed to refine the language syntax to
> something that people could learn and apply in a reasonable
> amount of time. IIRC there is a Channel9 video where Anders
> explains the evolution of Async Await.
In other words - explicit asynchrony where a thread immediately
returns with Future[T] and moves on to the next task. It’s just
hidden by Async/Await.
More information about the Digitalmars-d
mailing list