Skip to content
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: multiple value/tuple channels #41148

Closed
lolbinarycat opened this issue Aug 31, 2020 · 7 comments
Closed

proposal: Go 2: multiple value/tuple channels #41148

lolbinarycat opened this issue Aug 31, 2020 · 7 comments
Labels
FrozenDueToAge LanguageChange Suggested changes to the Go language Proposal Proposal-FinalCommentPeriod v2 An incompatible library change
Milestone

Comments

@lolbinarycat
Copy link

There have been several requests over time for tuples to be added to go. However, that presents issues with return values. I propose a change with a much smaller scope: multi-value channels:

var multiChan := make(chan (int,string),3)

multiChan <- 6, "foo"
multiChan <- 7, "bar"

n, str  := <- multiChan
n2, str2, ok := multiChan // check if channel is closed

The reason for this is as follows:
Normally, you don't really need tuples because you can pass around multiple variable and just know that they are associated.
However, in an environment with multiple goroutines, you can't be sure exactly in what order things would happen, and the only way to associate related variables is with a struct type.

Here is the code that inspired me to write this (somewhat incomplete, as I stopped writing it

func getRootWinNameAtom() xproto.Atom {
	props, err := ListProperties(X,X.RootWin()).Reply()
	if err != nil {log.Fatal(err)}

	// this is why go needs tuples
	type CookieWithAtom = struct {
		C xproto.GetAtomNameCookie,
		A xproto.Atom,
	}
	
	cookies := make(chan CookieWithAtom,props.AtomsLen)
	for _, atom := range props.Atoms {
		go func (atom xproto.Atom) {
			cookies <- CookiesWithAtom{GetAtomName(X,atom),atom}
		} (atom)
	}

	type ReplyWithAtom = struct {
		R xproto.GetAtomNameReply,
		A xproto.Atom
	}

	replies := make(chan ReplyWithAtom,props.Atoms)
	for i:=0;i<len(props.Atoms);i++ {
		go func {
			c := <-cookies
			replies <- ReplyWithAtom{c.R.Reply(),}
			log.Println("got reply")
		}
	}
}

As you can see, half the code is just defining temporary types to use, where as it would be much less with my proposal.

This problem would also be addressed somewhat by #1285, as it would allow easily using anonymous types in the type signature of the channel.

@gopherbot gopherbot added this to the Proposal milestone Aug 31, 2020
@ianlancetaylor ianlancetaylor changed the title Proposal: Multiple value/tuple channels proposal: Go 2: multiple value/tuple channels Aug 31, 2020
@ianlancetaylor ianlancetaylor added v2 An incompatible library change LanguageChange Suggested changes to the Go language labels Aug 31, 2020
@ianlancetaylor
Copy link
Contributor

For language change proposals, please fill out the template at https://go.googlesource.com/proposal/+/refs/heads/master/go2-language-changes.md .

When you are done, please reply to the issue with @gopherbot please remove label WaitingForInfo.

Thanks!

@ianlancetaylor ianlancetaylor added the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Aug 31, 2020
@andig
Copy link
Contributor

andig commented Sep 5, 2020

Why wouldn‘t one use a channel of struct instead?

@lolbinarycat
Copy link
Author

Why wouldn't one use a channel of struct instead?

like I showed in my examples, that requires defining a new type (or typing out an anonymous struct type every time), which can be cumbersome.

@lolbinarycat
Copy link
Author

Would you consider yourself a novice, intermediate, or experienced Go programmer?
intermediate, I guess. I haven't been using go for very long necessarily, but I have written a good deal of go code.

What other languages do you have experience with?
I have a bit of experience with:
haskell, rust, js, c and emacs-lisp (I might be forgetting something).

Would this change make Go easier or harder to learn, and why?
It would make it a little bit harder, but it wouldn't be a huge difference.

Has this idea, or one like it, been proposed before?
Some proposals have been made for tuples.

If so, how does this proposal differ?
It only applies to channels

Who does this proposal help, and why?
People who want to send associated data through a channel.

What is the proposed change?
Please describe as precisely as possible the change to the language.
It would be possible to send associated pairs/triples/etc. through channels.

What would change in the language spec?
Channels

Please also describe the change informally, as in a class teaching Go.
channels can now send and revive multiple values, similar to functions.

Is this change backward compatible?
yes.

Breaking the Go 1 compatibility guarantee is a large cost and requires a large benefit.
Show example code before and after the change.
What is the cost of this proposal? (Every language change has a cost).
The biggest cost would probably be how it interacts with the optional ok paramater, as now seeing a, b := <- ch could have multiple meanings.

How many tools (such as vet, gopls, gofmt, goimports, etc.) would be affected?
anything that cares about channels in a meaningful way.

What is the compile time cost?
the amount of variables that it is valid to assign via a channel receive now depends on the type of the channel.

What is the run time cost?
none.

Can you describe a possible implementation?
A translation tool that changes multi-value send and receives into their anonymous struct type equivalent

Do you have a prototype? (This is not required.)
How would the language spec change?
channel types:

ChannelType = ( "chan" | "chan" "<-" | "<-" "chan" ) (ElementType | TupleType ) .
TupleType = "(" [ElementType [","] ] ")"

Orthogonality: how does this change interact or overlap with existing features?
The biggest overlap is with struct values.

Is the goal of this change a performance improvement?
no
If so, what quantifiable improvement should we expect?
How would we measure it?
Does this affect error handling?
not in any obvious way.
If so, how does this differ from previous error handling proposals?
Is this about generics?
no
If so, how does this differ from the the current design draft and the previous generics proposals?

@lolbinarycat
Copy link
Author

@gopherbot please remove label WaitingForInfo

@gopherbot gopherbot removed the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Sep 7, 2020
@ianlancetaylor
Copy link
Contributor

As mentioned above, we can just use a struct type. This proposal is syntactic sugar for that. If we're going to add a new tuple type, it should be more consistent than just syntactic sugar for channels. See also #32941.

Therefore, this is a likely decline. Leaving open for four weeks for final comments.

@ianlancetaylor
Copy link
Contributor

No further comments.

@golang golang locked and limited conversation to collaborators Oct 13, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge LanguageChange Suggested changes to the Go language Proposal Proposal-FinalCommentPeriod v2 An incompatible library change
Projects
None yet
Development

No branches or pull requests

4 participants