Skip to content

proposal: spec: provide way to easily turn channel into readable-only / writable-only channel #22189

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

Closed
leonklingele opened this issue Oct 9, 2017 · 6 comments
Labels
FrozenDueToAge LanguageChange Suggested changes to the Go language Proposal v2 An incompatible library change
Milestone

Comments

@leonklingele
Copy link
Contributor

This has been sitting in my queue for quite a while now and after finding #21953, I think it's time to publish this proposal.

Proposal

The problem

Consider the following example:
You create a channel and pass it directly to a producer and a consumer; the producer puts data onto the channel, while the consumer reads this data from the channel.
Although this works fine, there's a drawback: a consumer might as well read data from the channel instead of writing to it and a producer may write to the channel instead of reading from it.

Existing solutions

There are three already existing solutions to this problem:

  1. Specify in the function signature of the producer and consumer what they should be allowed to do with a channel (func producer(c chan<- *data) / func consumer(c <-chan *data))

  2. Create concrete helper functions to turn an RW channel to an R-only / W-only channel as illustrated in this example: https://play.golang.org/p/ats2aDDbEi

  3. Define an interface (applicable to some cases only)

The problem with these solutions

Solution 1. is too permissive, permissions to read / write should be granted by the caller (the main func in the given example), not the callee (i.e. producer / consumer)

Solution 2. works, but is ugly. It shouldn't be that hard to make a channel readable / writeable only. Also, as long as Go has no generics (proposal here), these two helper functions (onlyReadable / onlyWritable) are required for every type which is sent over a channel.

A better solution?

Only aware of these solutions, I propose a fourth:

// producer may only write into the channel c, or close it
go producer(c<-)

// consumer may only read from the channel c
consumer(<-c)
@davecheney
Copy link
Contributor

davecheney commented Oct 9, 2017 via email

@randall77
Copy link
Contributor

You can do solution 1, and enforce it in main, like this:

func main() {
	c := make(chan int)
	var c0 chan<- int = c
	var c1 <-chan int = c
	send(c0)
	receive(c1)
}
func send(c chan<- int) {
	c <- 7
}
func receive(c <-chan int) {
	<-c
}

@dsnet dsnet added v2 An incompatible library change LanguageChange Suggested changes to the Go language labels Oct 9, 2017
@leonklingele
Copy link
Contributor Author

@davecheney

If you disagree can you please provide a source code

https://play.golang.org/p/m8ZabPnjv6

Also, quoting myself

Solution 1. is too permissive, permissions to read / write should be granted by the caller (the main func in the given example), not the callee (i.e. producer / consumer)

@randall77 interesting, I wasn't aware of this. Thanks.
Still, I prefer consumer(<-c) over

var cr <-chan int = c
consumer(cr)

which not only requires a new dedicated variable, but also is harder to read / grasp.

@davecheney
Copy link
Contributor

Please seek Keiths example, this is how to do it in Go if you don’t trust the author of the function.

@davecheney
Copy link
Contributor

which not only requires a new dedicated variable, but also is harder to read / grasp.

This is a subjective argument. In general Go does not aim for maximum brevity, it aims for maximum clarity even if that involves an extra line or two.

@leonklingele
Copy link
Contributor Author

The more I look at my example, the more I dislike the proposed solution. consumer(<-c) doesn't even work (it's passing a value read from the channel, not a readable-only version of it). Sorry for dumping my ideas. At least I did learn something new, thanks for the suggestion @randall77.

@golang golang locked and limited conversation to collaborators Oct 9, 2018
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 v2 An incompatible library change
Projects
None yet
Development

No branches or pull requests

5 participants