On 10/23/17 22:40, Dmitry Olshansky wrote:
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.


That was actually my point. Windows and Linux/macOS .NET core do different things. It doesn't matter to the dev. You did a better job of illuminating it. :)

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.


And that is the difficulty we face in D. :)


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.


Yup.

--
Adam Wilson
IRC: LightBender
import quiet.dlang.dev;

Reply via email to