Hacker News new | ask | show | jobs
by KingOfCoders 1657 days ago
I understood from the OP that in Golang the sync and async code would be the same - contrary to e.g. Rust were you have async/wait. Go achieves this with coroutines and the go keyword.

f()

is a sync call to the function f, and the function f used async calls inside. Somewhere then needs to be a transition from async to sync contexts (aka wait/block).

I wondered where this happens.

From your comment I assume there is a difference, in sync code I would do

x = f()

while in async code I would use

f(channel)

?

1 comments

Close. If I execute say want to run some function asynchronously I use the go keyword to execute it. But I can't get a return value if I do that so I need some other mechanism to get the return value. One way is to pass a channel into the function and expect the function to return the value to me via that channel. like so:

    func f(ch chan[int]) {
     ch <- 1 // depending on the channel implementation this is a blocking action
    }
then I can call that function asynchronously

    go f(ch)
and later when I want the value from f I can retrieve it from the channel

    i := <-ch // this is a blocking call
The net effect of the all the above is that async and non async code is highly composable. if I have a function that computes a value and I want to get that value asynchronously then I can wrap it in a function that uses a channel to get the value to me.

    go func() { ch<-f() }
Every function is a potential asynchronous function.
"The net effect of the all the above is that async and non async code is highly composable."

How does this differ from Rust (Or Typescript etc.) where we would use

  async f() -> i32 { }

  fn g() { f().wait() }
to block?
Thanks a lot! Can only upvote you once sadly.