All this async code without decent locking primitives is leading to a rabbit hole of race conditions... It doesn't matter that it's all single threaded if all your function calls may or may not block and run a bunch of other code in the meantime, mutating all kinds of state. I feel like JavaScript developers of the 2020's are going to relearn the same things the C programmers of the 1990's learn, just a few levels of…
In a single-threaded universe, what more do you need to lock the world than a boolean variable?
V8 adds support for top-level await
51–60 of 310 posts
Re: V8 adds support for top-level await
#52All this async code without decent locking primitives is leading to a rabbit hole of race conditions... It doesn't matter that it's all single threaded if all your function calls may or may not block and run a bunch of other code in the meantime, mutating all kinds of state. I feel like JavaScript developers of the 2020's are going to relearn the same things the C programmers of the 1990's learn, just a few levels of…
Re: V8 adds support for top-level await
#53 const data = await fetch()
push(someData) // async, runs in the background
You would do: const data = fetch() // Runtime detects promise and awaits result
async push(data) // the async keyword would return a promise and execute the push function asynchronously, allowing the next line to execute
In this fantasy world the "await" keyword would work anywhere and as you'd expect – awaiting the result of any promise: const data = fetch() // implicitly await
await async push(data) // this would also be "synchronous" in that it suspends execution of subsequent code until `push` fulfills or rejects the promise, and so it'd have the same effect as implicit await
Point is you'd probably await that promise elsewhere, so you'd actually store away the return value of the `async` call and later on you'd `await`, or another example would be to await a block.Promise rejections in implicit awaits would halt execution, just like a sync function throwing an error, so you wouldn't "miss" an error somewhere because runtimes swallow promise rejections. (Well, at least Node wised up eventually.)
This means there'd be no difference in function declaration between sync and async functions, it'd be determined by whether they return a promise or not which I think should be possible to statically determine by a JIT compiler in most cases, so not adding too much (if any) overhead.
Kind of a half baked thought, but point is I always felt the async/await thing was kind of backwards in JavaScript.
Re: V8 adds support for top-level await
#54All this async code without decent locking primitives is leading to a rabbit hole of race conditions... It doesn't matter that it's all single threaded if all your function calls may or may not block and run a bunch of other code in the meantime, mutating all kinds of state. I feel like JavaScript developers of the 2020's are going to relearn the same things the C programmers of the 1990's learn, just a few levels of…
Isn't every new language doomed to relearn everything in some way?
Take a look at a Lisp, APL or a derivative, or Ada for examples of languages designed by people who knew what they were doing. Lisp grew in universities under the direction of hackers and there are several standard dialects now. APL was designed by a mathematician originally as a teaching aid. Ada was designed in a contest by the US DoD after spending a long while collecting requirements and it was then fully specified before any implementation work was done.
Re: V8 adds support for top-level await
#55Earlier quoted context omitted.
For some use cases, the difference can be a little more dramatic. fetch(allResourcesUrl).then(async response => { let allResources = await response.json(); let pageResource = await (await fetch(allResources.page1.url)).json(); // set up page with pageResource }); can be replaced with { let allResources = await (await fetch(allResourcesUrl)).json()); let pageResource = await (await fetch(allResources.page1.url)).json(…
What's with the `let` though?
Re: V8 adds support for top-level await
#56All this async code without decent locking primitives is leading to a rabbit hole of race conditions... It doesn't matter that it's all single threaded if all your function calls may or may not block and run a bunch of other code in the meantime, mutating all kinds of state. I feel like JavaScript developers of the 2020's are going to relearn the same things the C programmers of the 1990's learn, just a few levels of…
> It doesn't matter that it's all single threaded if all your function calls may or may not block and run a bunch of other code in the meantime, mutating all kinds of state. Can you elaborate a bit more on this? I'm unsure about how locking in a single-threaded environment would work. And how would it really differ from async/await or promises which can handle race conditions already? One area where the lack-of locki…
function transfer(amount, acct1, acct2) {
var current_balance = await acc1.balance()
if current_balance > amount {
await acct1.sub(amount)
await acct2.add(amount)
}
}
Now what happens if you get multiple calls to transfer? What you want is probably something like: function transfer(amount, acct1, acct2) {
await acct1.Lock()
....
await acct1.UnLock()
}Re: V8 adds support for top-level await
#57I think async/await probably makes more sense in a typed language, where a compiler can tell you when you're missing an await, or at least warn you about not dealing with potential side effects and error handling. For something like JavaScript, it'd make more sense to me to have the runtime always and implicitly await the result of async functions, and instead make developers explicitly say when they wish for the res…
Re: V8 adds support for top-level await
#58All this async code without decent locking primitives is leading to a rabbit hole of race conditions... It doesn't matter that it's all single threaded if all your function calls may or may not block and run a bunch of other code in the meantime, mutating all kinds of state. I feel like JavaScript developers of the 2020's are going to relearn the same things the C programmers of the 1990's learn, just a few levels of…
Data races are impossible in JavaScript because it's single-threaded. Race conditions are possible in any language that can do anything asynchronous, which is basically all of them. But the general benefit you get from JS being single-threaded is the fact that any given callback is transactional. No other code will ever come in and mutate state between two regular lines of JavaScript code. Achieving this is pretty mu…
How is this different from normal multithreading?
Re: V8 adds support for top-level await
#59Earlier quoted context omitted.
JS is single-threaded right so (...I think...) deadlocks are actually impossible. Although I guess you can still get stuck if two pieces of code are waiting on each other to satisfy some condition (and trading control of the sole thread) without using explicit locking.
Yeah, nothing about JavaScript being single threaded implies any resistance to deadlock.
Re: V8 adds support for top-level await
#60Earlier quoted context omitted.
Data races are impossible in JavaScript because it's single-threaded. Race conditions are possible in any language that can do anything asynchronous, which is basically all of them. But the general benefit you get from JS being single-threaded is the fact that any given callback is transactional. No other code will ever come in and mutate state between two regular lines of JavaScript code. Achieving this is pretty mu…
> two sequential lines of code are no longer two truly sequential instructions How is this different from normal multithreading?
You can wedge a NodeJS interpreter by not yielding, but you also have control over when that yielding happens.