var foo = await bar();
vs c1 := make(chan float64, 1)
go bar(c1)
foo := <-c1
Sure you have to be in an async method to use await but its really not that bad if you embrace it.Go seems better suited for high throughput message passing.
foo := bar()
and if bar() is a function that does something annoying or time-consuming before finishing its work and returning the value, it just behaves like a normal, synchronous function call. “Await” is, as TFA explains, syntactic sugar for slapping an async function into behaving like a normal synchronous function call. In Go there is no reason you can’t just write your function calls synchronously in the first place.That's syntactically different though, isn't it? Would the Go runtime lock you to that specific thread and block it or sleep that goroutine and move it to another thread when its no longer sleeping? Maybe in Go there's no difference in those concepts but in many languages certain threads are special. UI threads are often used for event serializiation but beyond that you might have a GL context on a specific thread.
How does Go manage that? How do you protect yourself from the runtime splitting your single thread work at a point you didn't intend? You probably have to make sure you only have a main goroutine that runs in a threaded way (as they do) and pass messages to it.
I can't really find an idiomatic Go UI example so I don't know what the answer is.
By default, the Go runtime does not guarantee any affinity between Go-level threads (goroutines) and OS threads. There's a way to forcibly pin a goroutine to a specific thread[1], but it limits your concurrency.
The Go approach does indeed cause problems wrt. OS-thread-affine state. It's a tradeoff. For RPC-oriented network services, the Go niche, OS thread state is very rare.
There are exactly the same reasons in Go to want asynchronous calls as there are in C# or Java or C++, except that performance of multi-threaded code (which is the semantics of goroutines) is much nicer in Go. Sure, channels can sometimes be a nice alternative to locking, if you can afford all of the copying.
But Go is stuck with only multi-threaded code + synchronous calls + locking/channels, whereas in C# or Java or even C++ you can chose between using that OR asynchronous code with futures.
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?
Golang functions only have one colour. This colour may be closer to "red" than "blue", but at least you never need to concern yourself with this as the consumer of an API, and you can count on the rest of the language having been designed around what is possible with these "purple" functions, as opposed to JS where the situation is that the language provides you with plenty of nice features to structure your code on paper but the design of existing code you need to interface with prevents you from effectively using them.
Neither does the C# snippet. In fact, if you want to extract the result of the function call as well, you can still keep you API as is in C#, and use Task.wait() or something similar to block execution until the task is finished, and read its result.
In Go there is no such alternative: if you have a value-returning function, and want to run it asynchronously and continue when the value is available, you have to re-write the function into a void function and add as many channel parameters as return values it held (or wrap the original function with something which calls it synchronously and then pushes those values on the channels),or use some shared memory to store the results. And make sure to also catch any panics the function might raise, if you were planning to handle panics.
I would not be surprised if some future version of Go introduces async/await to handle all of this complexity for you, except that Go developers usually hate making things easier for their users.
Edit to add: channels in Go actually tend to impose colors on functions just as much as async/await in C#. You can't call a function which returns its result in a channel synchronously, you must start it in a separate goroutine. Unfortunately, the compiler doesn't know this and will let you create a silly deadlock that way.
You can't if you want to free the OS thread while waiting for result.
var foo = await bar();
is foo := bar()
Go concurrency is much nicer because it doesn't have colored functions. You can use the same functions and library both synchronously and concurrently in millions of goroutines. foo := bar()
In Go is equivalent to auto foo = bar();
In C#, in terms of semantics.It is true that, due to the runtime implementation,
go foo()
Is significantly less wasteful than new Thread(() => foo());
So there is less of a need for async code in Go.But if you want to start multie things in parallel and await all of them, or if you want to create asynchronous workflows that modify shared resources without locking, you don't have any Go library or construct to help, which was precisely what async/await gives you.
const foo = await Promise.all(randomArray.map(bar));
I would have to google stuff to know where to start for the golang version.