4 ms·
The point of the construct is not explicitly waiting for child tasks/threads/whatever, but that as a formal restriction, you cannot leave the scoped block with
by wokwokwok 9y ago
The point of the construct is not explicitly waiting for child tasks/threads/whatever, but that as a formal restriction, you cannot leave the scoped block with unresolved tasks.
I don't believe either of the constructs you've mentioned do this, and I'm not aware of any that do.
The trivial counter example would be a deeply nested `setTimeout(..., 5000)` inside the javascript code.
It doesn't matter if you've called Promise.all or not.
Also, regarding parallelism: Obviously async/await are for that; this is basically pitching an equivalent construct for parallel processing.
I think this is novel, frankly, and the alternatives being thrown around by people are by people who didn't read the article.
- joshuamorton 9y ago>The trivial counter example would be a deeply nested `setTimeout(..., 5000)` inside the javascript code. Well of course, setTimeout isn't async/await based, its callback based. If instead you only had this api, you could make that formal assertion: await promiseSetTimeout(time).then(...); And in fact you can write promiseSetTimeout today! So basically, async/await provides this as long as you only use async/await. In JS you can't formally assert this because there are functions that subvert the normal control flow, but if you outlaw those, you absolutely can.
- wokwokwok 9y ago> as long as you only use async/await... Well, what if you don't? That's the point. The proposed construct does not require that: I'm not saying its better or worse; I'm just pointing out that it's different. Obviously if you choose to avoid branching code in your functions, they won't branch; what's novel here is that the closing scope (ie. in this case, the collapse of the python with block) triggers a collection of all the ambient tasks started in that context. I'm sure you could implement something similar in javascript, but it is not the same as Promise.all.
- joshuamorton 9y ago>Well, what if you don't? This is kind of a silly question. Its always possible to subvert a safe construct system if you try hard enough. You can write unsafe blocks in rust. You can pass in a callback to a nursery, as is described in the article. >The proposed construct does not require that Well, kind of. The article actually explicitly states that >Here's a simpler primitive that would also satisfy our flow control diagram above. It takes a list of thunks, and runs them all concurrently: which is equivalent to promise.all, satisfies the invariant nurseries do, except in very specific circumstances (unbounded while loop-y constructs). And you just simply can't use promise.all in that situation.
- wokwokwok 9y agoOh come on. I don't agree that the proposed idea is fundamentally new and amazing; but I think it is novel, and there may be some value in being able to semantically bind tasks to execution points, specifically when the tasks are spawned in naive (or uncontrolled, eg. library) code, and have not explicitly opted in to the scheme. Does this particular implementation do that perfectly? No, probably not. ...but I think the idea of it has some merit. There's more value here than just waiting for a series of deferred tasks that you have explicitly created, and explicitly opted into a specific concurrency workflow with. Note specifically these parts of the proposal: > we declare that a parent task cannot start any child tasks unless it first creates a place for the children to live ^-- This is not satisfied by your method, at all. > But the problem with this is that you have to know up front the complete list of tasks you're going to run, which isn't always true. Literally the next sentence after the one you quoted. > What if you really do need to write a function that spawns a background task, where the background task outlives the function itself? Easy: pass the function a nursery object. There's no rule that only the code directly inside the Notice how you can avoid the 'setTimeout(() => { .. })` in nested code issue by explicitly passing in a context that has its own scope. ... There's a lot of stuff in here that is actually quite thoughtful. You don't have to dig through it, finding every little nitpick you can to call it out on; just think about the idea being proposed. It's certainly not 'just promises'; if you think it is, then... I don't know what to say. You're wrong. :P
- 9y ago