3 ms·
> There are exactly the same reasons in Go to want asynchronous calls Which isn’t the comparison I’m replying to here. Calling an asynchronous function with “a
by philwelch 6y ago
> There are exactly the same reasons in Go to want asynchronous calls
Which isn’t the comparison I’m replying to here. Calling an asynchronous function with “await” forces it to behave synchronously. You would only do such a thing if you were operating in a framework or language with colored functions.
> in C# or Java or even C++ you can chose between using that OR asynchronous code with futures.
Java, C#, and C++ have channels?
- tsimionescu 6y ago> Calling an asynchronous function with “await” forces it to behave synchronously. You would only do such a thing if you were operating in a framework or language with colored functions. I don't really think you are right. When you await an async function, you let the async function run asynchronously, but suspend your own execution until you can receive the result from that function (an actual return value, an exception, or simply termination for void functions). Calling a function directly forces it to run on the same execution thread as you. Calling it with await allows it to run in any thread. This is the actual advantage, and Go doesn't have any equivalent construct that is as convenient for this use case. Also, note that a function that expects to return data through channels can't be called in a sync manner in Go or it will deadlock. So in essence there is function coloring in Go as well. > Java, C#, and C++ have channels? Not out of the box, but they are easy to replicate if desired, wrapping a lock in a send/receive interface (you can add a buffer as well if desired). It is probably not as efficient, but it may not be vastly different either.
- philwelch 6y ago> Calling a function directly forces it to run on the same execution thread as you. Calling it with await allows it to run in any thread. This is the actual advantage, and Go doesn't have any equivalent construct that is as convenient for this use case. OK so Thread A calls “await” on a coroutine that executes in Thread B (where B may or may not be A). Thread A is now blocked on that coroutine. What have I gained by running that coroutine in Thread B? One potential answer is that while Thread A is blocked by “await”, it can context-switch to a different coroutine. You can effectively do similar things in Go if you want to. But doing so abandons the guarantee that Thread A will pick up where it left off as soon as Thread B is finished. > Also, note that a function that expects to return data through channels can't be called in a sync manner in Go or it will deadlock. So in essence there is function coloring in Go as well. Is this a popular or idiomatic interface for Go library code to the same degree it is for “async” libraries in other languages? In isolation I find it more understandable to do channel writes as an explicit side effect than to manage futures but maybe that’s just my brain. > Not out of the box, but they are easy to replicate if desired I’m pretty sure you could implement futures and async/await using Go channels too if you wanted to.
- tsimionescu 6y ago> OK so Thread A calls “await” on a coroutine that executes in Thread B (where B may or may not be A). Thread A is now blocked on that coroutine. What have I gained by running that coroutine in Thread B? If the task that bar() will return is created when you first call it, then you're right, we didn't gain much. However, the task may have already been running for a long time behind the scenes, we may have done things in parallel with that run, and now that we need the result, we can block. For example: myHttpClient.StartReq1() myHttpClient.StartReq2() auto Res1 = await myHttpClient.WaitReq1() auto res2 = await myHttpClient.WaitReq2() > I’m pretty sure you could implement futures and async/await using Go channels too if you wanted to. Given the lack of generics, you would get a much worse interface. Btw, here is what a non-buffering channel would look like in Java: class Channel<T> { T value; void publish(T value) { synchronized(this) { this.value = value; try { this.wait(); } catch (InterruptedException e) {} } } T consume() { synchronized(this) { this.notify(); return this.value; } } }
- philwelch 6y ago> If the task that bar() will return is created when you first call it, then you're right, we didn't gain much. However, the task may have already been running for a long time behind the scenes, we may have done things in parallel with that run, and now that we need the result, we can block. So in Go that’s just a blocking channel receive.
- jayd16 6y agoNot exactly. Async allows for N tasks of linear code execution on the same thread at the cost of managing cooperative yields. Go and channels allow you to block many threads with little overhead and little syntax but at the cost of not being able to easily target a single thread without manual orchestration through channels. Consider a scatter/gather algorithm. N async tasks, N coroutines. Start N from the main thread and block until all complete. Simple right? Its not! Imagine there are GPU commands that must be grouped or even logs where you want some of the subroutine's logs to be grouped. With async/await you have the verbosity to synchronize tasks to thread contexts such that you know chunks will not be run in parallel. Its easy to control when execution leaves the current thread. It can ensure that it both does or does not yield execution. You can easily switch between synchronized main thread execution and parallel chunks without any top down design. With goroutines you most likely would write the ordered results to a channel that was passed around. I'm not sure if channels support N inserts in an atomic fashion out of the box but if not it must be a channel of arrays or maybe some kind of control channel as well. Hopefully you have access to every piece of code you need to synchronize. This all assumes you can get away with a single main goroutine. If you need a single special OS thread for interop I'm sure its more complex. Its not just a blocking channel. Essentially the two paradigms can do everything but they both seem to excel in certain cases.
- jayd16 6y ago>Java, C#, and C++ have channels? Yeah they do but without green threads the implications are a bit different. You can use channels and OS threads though most code bases don't.