Most active commenters
  • raluk(3)
  • sedatk(3)

←back to thread

289 points kristoff_it | 14 comments | | HN request time: 1.713s | source | bottom
1. raluk ◴[] No.44609651[source]
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.
replies(3): >>44609880 #>>44610056 #>>44610348 #
2. sedatk ◴[] No.44609880[source]
Which languages do have such a thing?
replies(2): >>44610179 #>>44610709 #
3. zmj ◴[] No.44610056[source]
That's because f2's result could depend on whether f1 has executed.
4. Twey ◴[] No.44610179[source]
I suppose Haskell does, as `(+) <$> f1 <*> f2`.
replies(1): >>44612756 #
5. jayd16 ◴[] No.44610348[source]
you 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.
replies(1): >>44612839 #
6. steveklabnik ◴[] No.44610709[source]
Rust does this, if you don’t call await on them. You can then await on the join of both.
replies(1): >>44610738 #
7. sedatk ◴[] No.44610738{3}[source]
Is the "join" syntax part of the language?
replies(2): >>44611332 #>>44613040 #
8. tcfhgj ◴[] No.44611332{4}[source]
no

https://doc.rust-lang.org/std/future/macro.join.html

replies(1): >>44612037 #
9. sedatk ◴[] No.44612037{5}[source]
Then it doesn’t apply in this case.
replies(1): >>44615353 #
10. raluk ◴[] No.44612756{3}[source]
In 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.
11. raluk ◴[] No.44612839[source]
This 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.
replies(1): >>44617730 #
12. deathanatos ◴[] No.44613040{4}[source]
Why 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.)

13. tcfhgj ◴[] No.44615353{6}[source]
why?
14. jayd16 ◴[] No.44617730{3}[source]
I 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.