Live data from Hacker News

Asynchrony is not concurrency

kristoff.it

141–150 of 228 posts

Re: Asynchrony is not concurrency

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

> As written, `asyncConcurrent(...)` is confusing as shit, and unless you memorize this blog post, you'll have no idea what this code means. I get that Zig (like Rust, which I really like fwiw) is trying all kinds of new hipster things, but half the time they just end up being unintuitive and confusing. Either implement (async-based) commutativity/operation ordering somehow (like Rust's lifetimes maybe?) or just use what people are already used to.

I can't agree. It is confusing, because you need to remember the blog post, it wouldn't be confusing in the slightest if you internalized the core idea. The question remains: is it worth it to internalize the idea? I don't know, but what I do know is some people will internalize it and try to do a lot of shit with this in mind, and after a while we will be able to see where this path leads to. At that point we will be able to decide if it is a good idea or not.

> "Asynchrony" is a very bad word for this and we already have a very well-defined mathematical one: commutativity.

It is risky to use "commutativity" for this. Zig has operators, and some of them are commutative. And it will be confusing. Like if I wrote `f() + g(). Addition is commutative, then Zig is free to choose to run f() and g() in parallel. The order of execution and commutativity are different things. Probably one could tie them into one thing with commutative/non-commutative operators, but I'm not sure it is a good idea, and I'm sure that this is the completely different issue to experimenting with asynchrony.

Re: Asynchrony is not concurrency

#142
post #38

The new Zig I/O idea seems like a pretty ingenious idea, if you write mostly applications and don't need stackless coroutines. I suspect that writing libraries using this style will be quite error-prone, because library authors will not know whether the provided I/O is single or multi-threaded, whether it uses evented I/O or not... Writing concurrent/async/parallel/whatever code is difficult enough on its own even if…

> I think that the code would have to be quite defensive and essentially assume the most parallel/concurrent version of IO to be used.

Exactly, but why would anyone think differently when the goal is to support both synchronous and async execution?

However, if asynchrony is done well at the lower levels of IO event handler, it should be simple to implemcent by following these principles everywhere — the "worst" that could happen is that your code runs sequentially (thus slower), but not run into races or deadlocks.

Re: Asynchrony is not concurrency

#143

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"

It is an attempt to delineate some classes of concurrent & parallel programming challenges using a new term (really, redefining it in the programming context to be a bit tighter).

Oxford dictionary holds no relevance here, unless it has took over a definition from the field already (eg. look up "file": I am guessing it will have a computer file defined there) — but as it lags by default, it can't have specific definitions being offered.

Re: Asynchrony is not concurrency

#145

Earlier quoted context omitted.

The difference is quite useful and informative. In fact, most places don't seem to state it strongly enough: Concurrency is a programming model. Parallelism is an execution model. Concurrency is writing code with the appearance of multiple linear threads that can be interleaved. Notably, it's about writing code . Any concurrent system could be written as a state machine tracking everything at once. But that's really…

Async JS code is parallel too. For example, await Promise.all(...) will wait on multiple functions at once. The JS event loop is only going to interpret one statement at a time, but in the meantime, other parts of the computer (file handles, TCP/IP stack, maybe even GPU/CPU depending on the JS lib) are actually doing things fully in parallel. A more useful distinction would be, the JS interpreter is single-threaded w…

> A more useful distinction would be, the JS interpreter is single-threaded while C code can be multithreaded.

...this seems like a long way round to say "JS code is not parallel while C code can be parallel".

Or to put it another way, it seems fairly obvious to me that parallelism is a concept applied to one's own code, not all the code in the computer's universe. Other parts of the computer doing other things has nothing to do with the point, or "parallelism" would be a completely redundant concept in this age where nearly every CPU has multiple cores.

Re: Asynchrony is not concurrency

#146
post #107

Earlier quoted context omitted.

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

See this is what the OP is getting at, this is only true for async implementations that don't have any parallelism. That doesn't have to be the case, there's no reason that your javascript runtime couldn't take await foo() await bar() and execute them in two threads transparently for you. It just happens, like the Python GIL, that it doesn't. Your JS implementation actually already has mutexes because web workers wit…

In the case of javascript, it's only allowed to do that when you can't detect it, situations where foo doesn't affect the output of bar. So as far as pitfalls are concerned it does one thing at a time. The rest is a hidden implementation detail of the optimizer.

Re: Asynchrony is not concurrency

#147

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

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

This isn't even remotely true; plenty of languages have both async and concurrency, probably more than ones that don't. C# was the language that originated async/await, not JavaScript, and it certainly has concurrency, as do Swift, Python. Rust, and many more. You're conflating two independent proprieties of JavaScript as language and incorrectly inferring a link between them that doesn't actually exist.

Re: Asynchrony is not concurrency

#148
post #70
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.

you mean like? await Join(f1(), f2()) Although more realistically Promise1 = f1(); Promise2 = f2(); await Join(Promise1, Promise2); But also, futures are the expression of lazy values so I'm not sure what else you'd be asking for.

This is what i hand in mind whit "manually handing of futures". In this case you have to write

   Promise1 = f1(); Promise2 = f2();
   v1,v2 = await Join(Promise1, Promise2);
   return v1 + v2
I think this is just too much of synthactic noise.

On the other hand, it is necessary becase some of underlying async calls can be order dependend.

for example

    await sock.rec(1) == 'A' && await sock.rec(1) == 'B'
checks that first received socket byte is A and second is B. This is clearly order dependant that can't be executed concurrently out of order.

Re: Asynchrony is not concurrency

#149
post #91
post #67

Earlier quoted context omitted.

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

You're not reporting yourself, though, since you didn't make it clear at all in your initial comment you were talking about hardware. The previous comment you made only mentioned "parallel data races" in a conversation about software ecosystems, where both of those terms are regularly used to describe things that occur. You're laughing about dunking on people who you've run up to in the middle of a football field; no one stopped you from scoring because you didn't tell them that you're apparently playing an entirely different game on your own.

Re: Asynchrony is not concurrency

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

> Usually, ordering of operations in code is indicated by the line number

Except for loops which allow going backwards, and procedures which allow temporarily jumping to some other locally linear operation.

We have plenty of syntax for doing non-forwards things.

Post reply on HN