-
Notifications
You must be signed in to change notification settings - Fork 17.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
proposal: Go 2: Make goroutine return channel with function result (promise) #33046
Comments
Looks a lot like #25821. |
Also #26287. |
This proposal is simpler than the two above though. However what is unclear in this proposal is how the goroutine started would write to the channel created. |
the idea is, that compiler will automatically write the result of a function to the channel, so the proposal is just a syntax sugar |
Ok, but you could only write one result like that, right? How could I write many results, perhaps, live, while my goroutine is running? Or is that not needed? |
For a function
Of those options, this proposal chooses option 3, which raises some questions (closely related to the ones in my Rethinking Concurrency GopherCon talk):
|
I am somewhat concerned that this approach would be too error-prone. Particularly:
|
Looks interesting. |
|
|
Today, that pattern is an explicit, conscious choice from among several options. By baking it into the language, this proposal would promote channel-based asynchronicity to a default, so that the choice not to use this pattern would require more thought than the choice to use it. That's what I'm worried about. |
Here's a fifth alternative: for a function When the goroutine exits, the pointers would be set to its results and then the final That would make your example read like: r1, r2, done := go myFunc()
[…] // Actually do something concurrently here, because why else would you want the goroutine?
<-done
fmt.Println(*r1, *r2)
func myFunc() (string, int) {
time.Sleep(time.Second)
return "hello", 3
} That handily resolves the questions about when the channels are closed or whether In exchange it introduces some potential pointer/value confusion, particularly if the results are passed as type (Note that the original proposal has exactly the same problem, since |
Personally, I think the |
If we had generics, we could write a version of this operation easily enough: func GoAndReturn(type T)(f func() T) chan T {
c := make(chan T)
go func() {
c <- f()
}()
return c
} Adding this to the language would make it easier to support passing arguments to the function, and returning multiple results from the function. But those seem like relatively minor enhancements to the basic idea, and of course you could write a generic version for any specific combination of number of arguments and results. |
@ianlancetaylor, note that that particular generic implementation has the same usability problems described in #33046 (comment). (Namely, it is too easy to accidentally read the channel too many or too few times.) That is: implementing this in user code may be straightforward, but the specific details needed to do it robustly are apparently not obvious. |
@bcmills Agreed, but I don't see how this proposal make those issues any better. The point is, as far as I can see, anything we can add to the language can also be done using a generic function. |
This proposal should also apply to deferred function calls. |
I'm not at all sure how that would work. func Example() {
v := defer func() int {
return 3
}()
// What is v? The function hasn't actually been run yet.
fmt.Println(v)
// Now the deferred function gets run. Did v have any kind of value before this?
} |
|
It seems that any approach we add to the language here can be done with a generic function, if we had generics. Therefore, this is a likely decline. It can be reopened if we are unable to add generics to the language. Leaving open for four weeks for further comments. |
Alternatively, we can make the |
@tema3210 I'm not sure quite what you are suggesting, but it sounds like a different proposal. There were no further comments on this proposal, so closing. |
If you starting a goroutine, for example:
It's pretty hard to get the result of function execution. You need to create a channel
It could be nice if go will return channel with the first argument of a function.
Example:
If a function returns several elements, several channels could be returned, (compiler should handle the optimization and create only one real channel)
Example:
So this proposal is no more than syntax sugar, the result of function should be automatically sent to channel by go compiler.
The text was updated successfully, but these errors were encountered: