Live data from Hacker News

Asynchrony is not concurrency

kristoff.it

191–200 of 228 posts

Re: Asynchrony is not concurrency

#191

Earlier quoted context omitted.

Well, consider the difference between a().then(() => b()) .then(() => c()) Compared to await a() await b() await c() Even for this simple case I think it's much clearer. Then look at a more complex case: for( i=0; i Now try re-writing this with then() and see the difference.

For the first one, it really feels like only a matter of how you break lines. Sure there is also the matter of anonymous function syntax, but The latter is more fair, here is a possible solution: const gen = (function* () { for (let i = 0; i !next.done && next.value.then(() => run(gen.next())); run(gen.next()); Or something similar using reduce. But in both cases, it illustrates the point, I guess. But if we are at p…

Well, sure, if you have `yield`, you pretty much have `await` already, as `await` is thin syntactic sugar on top of `yield` in all languages other than OCaml.

Re: Asynchrony is not concurrency

#192
post #175

Earlier quoted context omitted.

That resonates. Testing asynchronous and multithreaded code for all possible interleavings is notoriously difficult. Even with advanced fuzzers or concurrency testing frameworks, you rarely gain full confidence without painful production learnings. In distributed systems, it gets worse. For example, when designing webhook delivery infrastructure, you’re not just dealing with async code within your service but also ne…

> That’s why many teams now offload this to specialized services like Vartiq.com It would be nice to add a disclaimer that this is a system you're working on.

Thanks for pointing out. Edited. :)

Re: Asynchrony is not concurrency

#193
post #52

The author does not seem to have made any non-trivial projects with asynchronicity. All the pitfalls of concurrency are there - in particular when executing non-idempotent functions multiple times before previous executions finish, then you need mutexes!

> All the pitfalls of concurrency are there [in async APIs] This is one of those "in practice, theory and practice are different" situations. There is nothing in the async world that looks like a parallel race condition. Code runs to completion until it deterministically yields, 100% of the time, even if the location of those yields may be difficult to puzzle out. And so anyone who's ever had to debug and reason abou…

Idk, I work in typescript though but I do have race conditions that look exactly like those of concurrent software.

In particular promise.all([f,f,f]) where I want to ensure that I only Run the body of f a single time.

Re: Asynchrony is not concurrency

#194
A good way to gauge if "asynchrony" is a term we need is to test if it is useful in other contexts than just a single language, or a single concurrency design.

If it's needed to reason correctly in a wide set of concurrency models, then I'd say it's going to be a useful addition. If not, then I'd say it's not really worth using in the grander scheme of things.

I.e., does this make any sense in Haskell, Erlang, OCaml, Scheme, Rust, Go, .... ?(assuming we pick one of the many concurrency models available in Haskell, Rust and OCaml).

More generally: if things are cooperatively scheduled, then there's a need for attention to additional details. This is because it's much easier for a bad piece of code to affect the system as a whole, by locking it up, or generating latency-problems. In a preemptively scheduled world, a large group of problems disappear instantly, since you can't lock up the system in the same way.

Re: Asynchrony is not concurrency

#195
post #157

Defining async is hard. And I'm writing this as one of the many people who designed async in JavaScript. I don't quite agree with the definition in this post: just because it's async doesn't mean that it's correct. You can get all sorts of user-land race conditions with async code, whether it uses `async`/`await` (in languages that need/support it) or not. My latest formulation (and I think that it still needs work)…

i am not even sure we should define async

it may be hard (it is) because it cannot be matched to one thing

the question is: is it useful to define async? or event loop? there must be tons of concepts i have no idea in the realm of physical chips that make true parallelism possible

i am totally fine with "user finger" and "quickies", job queues and blocking or non-blocking APIs

the finger symbolizes touch events and even mouse clicks and keyboard or general user initiated events, which i have to match to quickies which are very tiny (execution time) blocking(!) jobs that will be queued by the browser

to reach my goals, i prefer non-blocking APIs because i can discard some time consuming jobs to underlying systems and i jsut write a quicky for what i want (store data in indexed db) and what will happen if it succeeds or fails etc (different quickies)

sync, async do not really help me, of course i have to understand when others talk about it or i see or use (or my preferred AI coder) async, but it just means non-blocking API

but again, the async programming model is actually writing very much blocking quickies where the non-blocking nature is the small, atomic nature (execution-time-wise) of the blocking jobs I try to match to chaotic, non-deterministic events, triggered by fingers or browsers or whatever

I actually dont care, just hope that the browser code uses great concurrent models with cpp or rust or whatever and the device has multiple executions units (os threads) and the os scheduler does a great job, managing things whether there are more execution units or just 1 available

async for me a not well defined concept and even if it was somehow defined, i am not sure it would be useful to me

useful concepts are events, the blocking nature of jobs i write in js, what my functions see (closure i guess), what runs as a job if i use APIs and what runs as a different job after the events the browser triggers (ready, error whatever)

even the name callback was extremely confusing because i really thought back then that the code somehow stops there and waits for a callback... no, it runs to the end of that section and you really have to understand what other things run when it "calls back" and what that code sees

to be honest, i think it is a mess and genius at the same time... but understanding "async" or rather the model was really difficult because i just dont think this means anything

it is actually very simple to understand with different concepts like event, blocking job, job queue, non-blocking API

what i also find important to know what we are doing and what others do like browser code, os etc... it is a bit like a cpp code declares a concurrent model with a thrad but the os will decide... in js, we use non-blocking api which implicitly declares a probably concurrent model the browser or node or whatever should use and i am sure they always do

the most important thing is to keep your jobs quick, probably under 30-50ms and non-blocking API are great because your job just declares the intent and done, and languages like cpp, rust will declare the os that they want the actual task done concurrently so even if the os has one real physical thread, the UI will be responsive since the OS will switch between UI code execution and "real task" execution like some networking or database or whatever

but all an "async" programmer has to do is to create a great UX model and match events to quickies

Re: Asynchrony is not concurrency

#196
post #155

Asynchrony, in this context, is an abstraction which separates the preparation and submission of a request from the collection of the result. The abstraction makes it possible to submit multiple requests and only then begin to inquire about their results. The abstraction allows for, but does not require, a concurrent implementation. However, the intent behind the abstraction is that there be concurrency. The motivati…

Completely agree. The server/client example in the post was just one example of a program not being able to make progress, you’ve just gave another which cannot be solved the same way, and I would bet there are many more that they will be discovering over time. IMO when async is used, concurrency needs to be ensured.

It depends on the API. If the only way to obtain the result of the asynchronous dispatch is a synchronous operation on a completion queue, then there are no cases where a single-threaded implementation will break, other than not providing the performance.

However, we can argue that if there is only a synchronous operation to collect the result, then it's not truly async. Asynchrony should mean not only that we can initiate a request without waiting for the result, but that the completion can happen at any time.

Re: Asynchrony is not concurrency

#198
post #61

I kind of think the author simply pulled the concept of yielding execution out of the definition of concurrency and into this new "asynchrony" term. Then they argued that the term is needed because without it the entire concept of concurrency is broken. Indeed so, but I would argue that concurrency makes little sense without the ability to yield and is therefore intrinsic to it. Its a very important concept but break…

Concurrency does not imply yielding... Synchronous logic does imply some syncing and yielding could be a way to sync - which is what i expect you mean. Asynchronous logic is concurrent without sync or yield. Concurrency and asynchronous logic do not exist - in real form - in von Neumann machines

Could you expand on what you mean?

Re: Asynchrony is not concurrency

#199
post #165

Earlier quoted context omitted.

While this is indeed the most common use, I'll bring as counter-examples Rust (or C#, or F#, or OCaml 5+) that supports both OS threads and async. OS threads are good for CPU-bound tasks, async for IO-bound tasks. The main benefit of having async (or Go-style M:N scheduling) is that you can afford to launch as many tasks/fibers/goroutines/... as you want, as long as you have RAM. If you're using OS threads, you need…

> The main benefit of having async (or Go-style M:N scheduling) is that you can afford to launch as many tasks/fibers/goroutines/... as you want Some have argued that the real solution to this problem is to "just" fix OS threads. Rumor has it Google has done exactly this, but keeps it close to their chest: https://www.youtube.com/watch?v=KXuZi9aeGTw https://lwn.net/Articles/879398/ Somewhat related and also by Google…

I think that PI will have a role, but I suspect that it can quickly destroy the performance of wasm code in unexpected ways.

As for fixing OS threads, indeed, this may very well change the ecosystem, but many developers expect their code to be cross-platform, so it might take a while before there is a solution that works everywhere.

Re: Asynchrony is not concurrency

#200

That’s word games. If I launch 2 network requests from my async JavaScript and both are in flight then that’s concurrent. Definition from Oxford Dictionary adjective 1. existing, happening, or done at the same time. "there are three concurrent art fairs around the city"

The concepts of concurrency and parallelism are adjacent enough that they are often confused. A lot of languages provide basic concepts for both but use different frameworks for both. So the difference really matters in that case. Or the frameworks are just a bit low level and the difference really matters for that reason (because you need to think about and be aware of different issues). I've been using Kotlin in th…

The idea behind Zig approach which is only being implemented is to extend concurrent code to be executable outside the coroutine context, making it trivially serializable when that's possible (thus the networking example).

In general, the heavy lifting should always be moved to the lower level infrastructure (compiler, standard library, RDBMS system in case of ACID guarantees...) — leaving developer his brainspace for the business logic.

This requires minimum "function coloring", and I'd prefer if Python took that approach instead.

Post reply on HN