I want to reflect on that this is still done without any garbage collector.
The Future object seems to do the all bookkeeping needed by the borrow checker (which I believe is what rust uses to track the lifetime of objects).
21–30 of 196 posts
I want to reflect on that this is still done without any garbage collector.
The Future object seems to do the all bookkeeping needed by the borrow checker (which I believe is what rust uses to track the lifetime of objects).
I'm waiting for the day when 'async' will be the default function type and 'await' will be the default type of function call. If anywhere down the callstack a function needs to await something it has to become an async function. And this needs to be done to the whole callstack recursively. So over time more and more functions of every codebase turn into async functions.
I'm waiting for the day when 'async' will be the default function type and 'await' will be the default type of function call. If anywhere down the callstack a function needs to await something it has to become an async function. And this needs to be done to the whole callstack recursively. So over time more and more functions of every codebase turn into async functions.
Having made "async" the default, you've just returned to regular threading, which is what we should have stuck with all along. The thread model is actually pretty useful, the pitfalls are well understood, and the tooling very mature.
In practice, most of your threads are in one form of wait loop or another and you've just got polling both inside the threads and with the scheduler.
Have a look at Erlang if you want a better model :) the erlang "processes" (different to os processes) can intelligently only wake up when there is work for them to do.
For a language to efficiently use cores, it really needs to include it's own scheduling.
Earlier quoted context omitted.
I feel like you're making a very interesting point but it seems a bit broad and abstract for me to justify in my head. Could you clarify what you mean?
If you want easier concurrency with higher overhead, that's exactly what OS threads do. The OS kernel is the "event loop" in this case, and they're highly optimized for this, though there is some overhead which is hard to avoid. Rust has gone back and forth on this. Pre-1.0 versions of Rust had a "green threads" mode. It was removed in favor of OS threads because it wasn't worth the complexity. Go is a language in wh…
Earlier quoted context omitted.
Not everything is a webserver/frontend/web related.
I'm curious as to why you think that matters? Async/Await are general purpose concurrent programming abstractions.
Making every function call asynchronous is likely to make most programs a lot slower.
Earlier quoted context omitted.
Not everything is a webserver/frontend/web related.
I'm curious as to why you think that matters? Async/Await are general purpose concurrent programming abstractions.
If we did the whole problem async (async by default as I interpret it) it would require so much bookkeeping to keep causality that would make it unreasonably difficult. For things that require causality like that, we are lucky that the default mode of computation is synchronous because it fits my problem domain perfectly.
That's why I say "not everything is web" because while async maps well to problems like a server-client type application, it doesn't map well to all problems like my problem for example. Also, as someone else said, sync is easier to reason about for problems that don't require a lot of parallelism.
I'm waiting for the day when 'async' will be the default function type and 'await' will be the default type of function call. If anywhere down the callstack a function needs to await something it has to become an async function. And this needs to be done to the whole callstack recursively. So over time more and more functions of every codebase turn into async functions.
This is exciting. It allows programmers to model their problems in code that fully accounts for the parallelism. For comparison, here is async/await in Zig: https://ziglang.org/documentation/master/#Coroutines Zig decided to go the other way - when you async call a function, it does eagerly evaluate until the first suspend point. This is less overhead than immediately suspending, plus it removes the dependency of the…
For a further comparison, Nim works in the same way as Zig when it comes to eager evaluation. Something that I'm particularly proud of when it comes to Nim's async/await implementation is that everything, right down to the macro which defines what `await` means, is implemented in the standard library. The compiler only implements the coroutines. This means that the language isn't bloated by this extra feature and makes it much easier for developers to implement their own async/await.
I believe there was talk to do the same in Rust, but for some reason the developers decided to implement it in the compiler instead.
I'm waiting for the day when 'async' will be the default function type and 'await' will be the default type of function call. If anywhere down the callstack a function needs to await something it has to become an async function. And this needs to be done to the whole callstack recursively. So over time more and more functions of every codebase turn into async functions.
This seems like the next logical step. A language where all functions are async/await. And it’ll likely pull in some nice features from academia like, building a dependency graph of async statements so it can automatically reorder async statements to get optimal concurrency.