5 ms·
One thing that most languages are lacking is expressing lazy return values. -> await f1() + await f2() and to express this concurently requres manually handing
by raluk 1y ago
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.
- sedatk 1y agoWhich languages do have such a thing?
- Twey 1y agoI suppose Haskell does, as `(+) <$> f1 <*> f2`.
- raluk 1y agoIn there is also ApplicativeDo that works nicely with this. do x <- f1 y <- f2 return $ x + y this is evaluated as applicative in same way.
- steveklabnik 1y agoRust does this, if you don’t call await on them. You can then await on the join of both.
- sedatk 1y agoIs the "join" syntax part of the language?
- tcfhgj 1y agono https://doc.rust-lang.org/std/future/macro.join.html https://doc.rust-lang.org/std/future/macro.join.html
- sedatk 1y agoThen it doesn’t apply in this case.
- tcfhgj 1y agowhy?
- sedatk 1y agoBecause parent asked for a language feature, not runtime: "One thing that most languages are lacking..."
- tcfhgj 1y agoI haven't linked a runtime but the specific feature, which alleviates manual handling of multiple futures when awaiting multiple futures concurrently, expressed in the language named Rust.
- deathanatos 1y agoWhy is having it be syntax necessary or beneficial? One might say "Rust's existing feature set makes this possible already, why dedicate syntax where none is needed?" (…and I think that's a reasonably pragmatic stance, too. Joins/selects are somewhat infrequent, the impediments that writing out a join puts on the program relatively light… what problem would be solved? vs. `?`, which sugars a common thing that non-dedicated syntax can represent (a try! macro is sufficient to replace ?) but for which the burden on the coder is much higher, in terms of code readability & writability.)
- zmj 1y agoThat's because f2's result could depend on whether f1 has executed.
- jayd16 1y agoyou 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.
- raluk 1y agoThis 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.
- jayd16 1y agoI suppose you'd have to make SumAsync(F1(),f2()); Buy it's kind of intractable, isn't it? Your language has to assume order dependency or independency and specify the other. Most seem to stick with lexical ordering implies execution order. I think some use curly brace scoping to break up dependency. I want to say kotlin does something like this. This is why they say async is a viral pattern but IMO that's because you're adding specificity and function coloring is necessary and good.