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

Created on 1 Sep 2020  路  7Comments  路  Source: golang/go

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.

Go2 LanguageChange Proposal Proposal-FinalCommentPeriod

Most helpful comment

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.

All 7 comments

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!

Why wouldn鈥榯 one use a channel of struct instead?

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.

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?

@gopherbot please remove label WaitingForInfo

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.

No further comments.

Was this page helpful?
0 / 5 - 0 ratings