> The term blocking isn't well defined. How slow does an operation have to be to be considered blocking? There are no rules.
The rule is very simple IMO, I already described it: if other execution can run while you wait for the value, it's blocking. (Edit: to be specific, other observable execution, so in your thread with write access to state you can see)
> Worse, async vs not async is about latency requirements of the caller,
I disagree. To me, async vs not async is about interruptibility. As you already mentioned, the code that computes a trillion digits of Pi is async if its interruptible, and not async if it isn't. If you're in a UI thread doing 60fps animation, async vs not async isn't really all that relevant (barring the slight inherent overhead in calling an async function). What you need is a profiler to tell you where you have a non-interruptible block consuming your 16ms. The compiler can't know this a priori, unless you make significant restrictions to the type of code you write (no unbounded loops, for instance).
> Such toolkits are almost never thread safe because it's too much hassle to program a thread safe renderer and would make it too slow, so that browser-specific implementation constraint propagates all over the JS ecosystem.
From here on you seem to not be aware of the fantastic recent developments in WebWorkers, it is now quite easy to spin up worker threads in JS, which communicate with the main thread via message passing.
> The rule is very simple IMO, I already described it: if other execution can run while you wait for the value, it's blocking. (Edit: to be specific, other observable execution, so in your thread with write access to state you can see)
is gmtime() blocking ? Technically it needs to ask kernel to get the time so it has same potential to block as any other call
> As you already mentioned, the code that computes a trillion digits of Pi is async if its interruptible, and not async if it isn't.
Very bad definition as either
* every single code is because kernel can always reschedule thread to do something else
* none of the compute code is if language runtime can't interrupt it (old versions of Go had that behaviour for tight loops IIRC)
* every of compute code is if language can arbitrarily interrupt it.
> From here on you seem to not be aware of the fantastic recent developments in WebWorkers, it is now quite easy to spin up worker threads in JS, which communicate with the main thread via message passing.
That's entirely worse approach as sharing any data structures is impossible and where mutex would be enough you're now shoveling tons of data around. It's workaround at best
It's like saying "my language is multithreaded because we started many processess and communicate via redis"...
I'd assume you missed my edit if you hadn't directly quoted it :) The kernel interrupting the thread doesn't meet the criteria of "other execution in your thread with write access to state you can see".
Web workers aren't threads. Threading is where you have two parallel streams of execution that share mutable memory. If there's no shared memory then what you've got is more like the older term "multi-processing".
> if other execution can run while you wait for the value, it's blocking.
How does that not capture any operation with a callback, and why does this definition depend on being "in your thread"? I don't think this is a definition that's widely used or understood.
> async vs not async is about interruptibility
By this definition Java fully supports async functions, because you can call Thread.interrupt() on any thread at any time. But I think most people would say Java doesn't do what is commonly understood by "async" including the Java developers themselves.
Your definition isn't as universal as you'd like to believe:
> Web Workers makes it possible to run a script operation in a background thread separate from the main execution thread of a web application. The advantage of this is that laborious processing can be performed in a separate thread, allowing the main (usually the UI) thread to run without being blocked/slowed down.
> How does that not capture any operation with a callback
You're right that my "blocking" definition is weak. I don't use the phrase in practice (It was introduced by the parent), preferring to think in terms of interruptibility [1]. The distinction I draw is between code that can assume no other code will interrupt it and much up it's view of global state, and that which cannot. The "in your thread" distinction is there because random kernel code or code from other applications (or code from other web workers) running doesn't muck up the thread-in-question's state. Those changes can only be observed across the boundaries of an `await` ("blocking") or in callbacks from separate events.
> I think most people would say Java doesn't do what is commonly understood by "async" including the Java developers themselves.
There's room in this world for multiple definitions. See above :)
[1] The question of "blocking" is a bit interesting, the execution thread wants to make a "blocking" call, but the runtime doesn't actually execute the syscall from that thread. It spins up a new thread to make the call, that thread gets blocked by the OS, and all the while the main execution thread continues running. Thus the call was "blocking" in some sense, but not to the thread in question, which was only "interrupted". The thread in question however is executing all sorts of other code while the assistant thread is blocked, so when the assistant thread returns and execution of that task resumes from being interrupted, it must ensure all the state it had observed beforehand is still valid.
This makes things confusing: the code which executes a trillion digits of Pi is blocking, but it is not interruptible. The code which reads a file or makes a network request via a syscall might be considered blocking, but it is interruptible.
The rule is very simple IMO, I already described it: if other execution can run while you wait for the value, it's blocking. (Edit: to be specific, other observable execution, so in your thread with write access to state you can see)
> Worse, async vs not async is about latency requirements of the caller,
I disagree. To me, async vs not async is about interruptibility. As you already mentioned, the code that computes a trillion digits of Pi is async if its interruptible, and not async if it isn't. If you're in a UI thread doing 60fps animation, async vs not async isn't really all that relevant (barring the slight inherent overhead in calling an async function). What you need is a profiler to tell you where you have a non-interruptible block consuming your 16ms. The compiler can't know this a priori, unless you make significant restrictions to the type of code you write (no unbounded loops, for instance).
> Such toolkits are almost never thread safe because it's too much hassle to program a thread safe renderer and would make it too slow, so that browser-specific implementation constraint propagates all over the JS ecosystem.
From here on you seem to not be aware of the fantastic recent developments in WebWorkers, it is now quite easy to spin up worker threads in JS, which communicate with the main thread via message passing.