4 ms·
JavaScript automatically starts the tasks and this is bad design IMHO. One loses referential transparency and the ability to run the workflow with different sch
by willtim 7y ago
JavaScript automatically starts the tasks and this is bad design IMHO. One loses referential transparency and the ability to run the workflow with different schedulers. It looks like Rust has done a better job.
- ralusek 7y agoJavaScript does not automatically start the tasks. It executes the function if you...execute the function. If you just want to pass around something with deferred execution, you can just pass the function around, or wrap it in a closure.
- willtim 7y agoIf I understand correctly, applying a JavaScript Async function is effectful and starts the background tasks. A better design is for the async function to yield an Async computation when applied. These computations can then be composed and passed around with full referential transparency. Only when we run the final composed Async computation, should the effects happen (threads running our computation). This is how the original F# asynchronous workflows were designed, which predate the C# and JavaScript implementations. Thankfully Rust works this way too!
- adgasf 7y agoIt does automatically start the tasks. JavaScript asyncs are "hot". You can simulate "cold" asyncs using a function, as you describe, but in other languages this is how they work by default.
- nwienert 7y agoI’m not sure exactly what hot is here, but if that’s the case then all javascript functions are hot. It’s behaving consistently with any other function. I assume the point here is that Rust in this case changes the way function calls work based on async, which is, well, inconsistent.
- int_19h 7y agoAn async function immediately returns a Future to the caller, so in that sense it is fully consistent with a sync function that immediately returns a value. If you want the asynchronously computed value, then the async equivalent to "foo()" is "foo().await", and that is also fully consistent - the function body starts running, and returns the value once it's done. But there's no sync equivalent of invoking an async function without awaiting it, which is where the hot/cold distinction manifests. Thus, there's no inconsistency, because there's nothing to be consistent with.
- kag0 7y agoOn referential transparency, I couldn't tell from the blog but are the Rust futures memoized/cached? If they are, then they're still not referentially transparent. But if they aren't then it might be a bit of a surprise to developers coming from other languages (especially ones not familiar with something like an IO monad).
- gdxhyrd 7y agoRust futures are just types that implement an interface providing a method to advance execution if possible and signal when they have more work to do.