Live data from Hacker News

Asynchrony is not concurrency

kristoff.it

91–100 of 228 posts

Re: Asynchrony is not concurrency

#91
post #67
post #52

Earlier quoted context omitted.

> 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…

> Code runs to completion until it deterministically yields No, because async can be (quote often is) used to perform I/O, whose time to completion does not need to be deterministic or predictable. Selecting on multiple tasks and proceeding with the one that completes first is an entirely ordinary feature of async programming. And even if you don't need to suffer the additional nondeterminism of your OS's thread sche…

And I repeat, if you think effects from unpredictable I/O completion order constitute equivalent debugging thought landscapes to hardware-parallel races, I can only laugh.

Yes yes, in theory they're the same. That's the joke.

Re: Asynchrony is not concurrency

#92
post #42
post #31

One thing that most languages are lacking is expressing lazy return values. -> await f1() + await f2() and to express this concurently requres manually handing of futures.

Which languages do have such a thing?

Rust does this, if you don’t call await on them. You can then await on the join of both.

Re: Asynchrony is not concurrency

#93
post #69

Earlier quoted context omitted.

Example 1 You can write to one file, wait, and then write to the second file. Concurrency not required. Example 2 You can NOT do Server.accept, wait, and then do Client.connect, because Server.accept would block forever. Concurrency required.

But why is this a novel concept? The idea of starvation is well known and you don't need parallelism for it to effect you already. What does zig actually do to solve this? Many other languages could already use async/await in a single threaded context with an extremely dumb scheduler that never switches but no one wants that. I'm trying to understand but I need it spelled out why this is interesting.

The novel concept is to make it explicit where a non-concurrent scheduler is enough (async), and where it is not (async-concurrent). As a benefit, you can call async functions directly from a synchronous context, which is not possible for the usual async/await, therefore avoiding the need to have both sync and async versions of every function.

And with green threads, you can have a call chain from async to sync to async, and still allow the inner async function to yield through to the outer async function. This keeps the benefit of async system calls, even if the wrapping library only uses synchronous functions.

Re: Asynchrony is not concurrency

#94
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…

>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. Quote from the article where the exact opposite is stated: > (and task switching is – by the definition I gave above – a concept specific to concurrency)

Well I'm having a hell of a time understanding what this article is trying to say. On a 3rd and 4th pass I think perhaps they mean task (in)dependency tracking is a fundamental concept. Independent tasks have "asynchrony." (Can we just say dependency and independency?)

But even with that definition, it seems like the idea of promises, task tracking, etc is well tread territory.

Then they conclude with how fire and forget tasks solve coloring but isn't that just the sync-over-async anti-pattern? I wouldn't be excited that my UI work stops to run something when there are no more green threads but they seem excited by it.

Anyway, I guess I got too distracted by the high concept "this is a fundamental change in thinking" fluff of the article.

Re: Asynchrony is not concurrency

#96

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!

You don't need mutex in async code, since there is no parallel execution whatsoever. In fact languages that use async programming as a first class citizen (JavaScript) don't even have a construct to do them.

If you need to synchronize stuff in the program you can use normal plain variables, since it's guaranteed that your task will be never interrupted till you give control back to the scheduler by performing an await operation.

In a way, async code can be used to implement mutex (or something similar) themself: it's a technique that I use often in JavaScript, to implement stuff that works like a mutex or a semaphores with just promises to syncronize stuff (e.g. you want to be sure that a function that itself does async operations inside is not interrupted, it's possible to do so with promises and normal JS variables).

Re: Asynchrony is not concurrency

#97
post #87

"Asynchrony" is a very bad word for this and we already have a very well-defined mathematical one: commutativity. Some operations are commutative (order does not matter: addition, multiplication, etc.), while others are non-commutative (order does matter: subtraction, division, etc.). try io.asyncConcurrent(Server.accept, .{server, io}); io.async(Cient.connect, .{client, io}); Usually, ordering of operations in code…

Strictly speaking commutativity is defined over (binary) operations - so if one were to say that two async statements (e.g. connect/accept) are commutative, I would have to ask, "under what operation?"

Currently my best answer for this is the bind (>>=) operator (including, incidentally, one of its instances, `.then(...)`), but this is just fuzzy intuition if anything at all.

Re: Asynchrony is not concurrency

#98
post #97
post #87

"Asynchrony" is a very bad word for this and we already have a very well-defined mathematical one: commutativity. Some operations are commutative (order does not matter: addition, multiplication, etc.), while others are non-commutative (order does matter: subtraction, division, etc.). try io.asyncConcurrent(Server.accept, .{server, io}); io.async(Cient.connect, .{client, io}); Usually, ordering of operations in code…

Strictly speaking commutativity is defined over (binary) operations - so if one were to say that two async statements (e.g. connect/accept) are commutative, I would have to ask, "under what operation?" Currently my best answer for this is the bind (>>=) operator (including, incidentally, one of its instances, `.then(...)`), but this is just fuzzy intuition if anything at all.

Commutative operations (all of them I think?) are trivially generalized to n-ary operations (in fact, we do this via ∑ and ∏, in the case of addition and multiplication, respectively). You're right that the question of what "operation" we're dealing with here is a bit hazy; but I'd wager that it's probably in the family of the increment operation (N++ === N + 1 = 1 + N) since we're constantly evaluating the next line of code, like the head of a Turing machine.

Edit: maybe it's actually implication? Since the previous line(s) logically imply the next. L_0 → L_1 → L_2 → L_n? Though this is non-commutative. Not sure, it's been a few years since my last metalogic class :P

Re: Asynchrony is not concurrency

#99
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"

Re: Asynchrony is not concurrency

#100
post #97
post #87

"Asynchrony" is a very bad word for this and we already have a very well-defined mathematical one: commutativity. Some operations are commutative (order does not matter: addition, multiplication, etc.), while others are non-commutative (order does matter: subtraction, division, etc.). try io.asyncConcurrent(Server.accept, .{server, io}); io.async(Cient.connect, .{client, io}); Usually, ordering of operations in code…

Strictly speaking commutativity is defined over (binary) operations - so if one were to say that two async statements (e.g. connect/accept) are commutative, I would have to ask, "under what operation?" Currently my best answer for this is the bind (>>=) operator (including, incidentally, one of its instances, `.then(...)`), but this is just fuzzy intuition if anything at all.

It's a good intuition. This has been studied extensively, the composition rule that is lax enough to permit arbitrary effects but strict enough to guarantee this class of outcomes is (>>=). We can keep trying to cheat this as long as we want, but it's bind.
Post reply on HN