proposal: a new syntax for sending values to channels #18511

Closed
yaxinlx opened this Issue Jan 4, 2017 · 5 comments

Comments

Projects
None yet
4 participants
@yaxinlx

yaxinlx commented Jan 4, 2017

Now, sending values to closed channels will panic, and sending values to channels is viewed as non-blocking operation. The two facts combined limits the possibilities of using the select mechanics.
So I proposal a special syntax for sending values to channels:

aChannel <-| value

When using this syntax to send values to closed channels, it will not panic but block the current goroutine. In other words, sending values to closed channels with the new syntax will be viewed as a blocking operation. This will create more possibilities to use the select mechanics.

Maybe adding another one would be better

aChannel <-? value

When using this syntax to send values to closed channels, it will neither panic nor block the current goroutine. In other words, sending values to closed channels with this new syntax is a no-op.

@yaxinlx yaxinlx changed the title from proposal: to proposal: a new syntax for sending values to channels Jan 4, 2017

@rsc

This comment has been minimized.

Show comment
Hide comment
@rsc

rsc Jan 4, 2017

Contributor

No, this would break unidirectionality of channels. Quoting myself in #11344:

Closing the channel is a send-like communication from the senders to the receivers that there will be no more sends. If
a sender later tries to send on the channel, then the goroutine who did the close is clearly confused. That merits a
panic, whether it is part of a select or an ordinary operation.

The fact that close is (like ordinary sends) a communication from sender to receiver is fundamental to its operation.
It comes up repeatedly that people want to use close as a reverse signal from receivers to senders to say "stop sending
to me". That is not what it means. It would break the unidirectionality of channels. And at least nine times out of
ten the people who want to do this have not completely thought through the implications of this kind of cancellation
mechanism. There almost always need to be two steps in a cancellation: a request for the cancellation and an
acknowledgement that work has in fact stopped. Close can serve as the latter; it cannot serve as both, and we make it
as hard as possible for people to do that accidentally.

This insistence that close is a sender -> receiver communication and not the reverse is also the reason why you cannot
close a receive-only channel.

Contributor

rsc commented Jan 4, 2017

No, this would break unidirectionality of channels. Quoting myself in #11344:

Closing the channel is a send-like communication from the senders to the receivers that there will be no more sends. If
a sender later tries to send on the channel, then the goroutine who did the close is clearly confused. That merits a
panic, whether it is part of a select or an ordinary operation.

The fact that close is (like ordinary sends) a communication from sender to receiver is fundamental to its operation.
It comes up repeatedly that people want to use close as a reverse signal from receivers to senders to say "stop sending
to me". That is not what it means. It would break the unidirectionality of channels. And at least nine times out of
ten the people who want to do this have not completely thought through the implications of this kind of cancellation
mechanism. There almost always need to be two steps in a cancellation: a request for the cancellation and an
acknowledgement that work has in fact stopped. Close can serve as the latter; it cannot serve as both, and we make it
as hard as possible for people to do that accidentally.

This insistence that close is a sender -> receiver communication and not the reverse is also the reason why you cannot
close a receive-only channel.

@rsc rsc added this to the Proposal milestone Jan 4, 2017

@rsc rsc closed this Jan 4, 2017

@davecheney

This comment has been minimized.

Show comment
Hide comment
@davecheney

davecheney Jan 4, 2017

Contributor
Contributor

davecheney commented Jan 4, 2017

@yaxinlx

This comment has been minimized.

Show comment
Hide comment
@yaxinlx

yaxinlx Jan 5, 2017

@rsc

... acknowledgement that work has in fact stopped ...

do you mean a solution like the second proposed fix in kubernetes/kubernetes#38857 ?

yaxinlx commented Jan 5, 2017

@rsc

... acknowledgement that work has in fact stopped ...

do you mean a solution like the second proposed fix in kubernetes/kubernetes#38857 ?

@yaxinlx

This comment has been minimized.

Show comment
Hide comment
@yaxinlx

yaxinlx Jan 5, 2017

@davecheney
by using nil channel to block a sending, the sender must clearly know the original channel is closed.
Yes, by obeying the rule that a channel should only be closed by a single sender, it is easy to assure this.
But sometimes, it would be easy to do programming by breaking this rule, then a sender will not know whether or not the channel is closed.

yaxinlx commented Jan 5, 2017

@davecheney
by using nil channel to block a sending, the sender must clearly know the original channel is closed.
Yes, by obeying the rule that a channel should only be closed by a single sender, it is easy to assure this.
But sometimes, it would be easy to do programming by breaking this rule, then a sender will not know whether or not the channel is closed.

@rsc

This comment has been minimized.

Show comment
Hide comment
@rsc

rsc Jan 5, 2017

Contributor

@yaxinlx I'm sorry but I don't understand what is going on in that issue. The code is clearly confused about whose job it is to close resultCh. The initial goroutine is closing the result channel (saying "nothing more will be sent here") and the new goroutine may still be trying to send on it (contradicting that). When you have a program like that, the solution is to rewrite the code so that it's clear who is responsible for signaling "nothing more will be sent on this channel" and when. The solution is not to paper over it with new operators.

Contributor

rsc commented Jan 5, 2017

@yaxinlx I'm sorry but I don't understand what is going on in that issue. The code is clearly confused about whose job it is to close resultCh. The initial goroutine is closing the result channel (saying "nothing more will be sent here") and the new goroutine may still be trying to send on it (contradicting that). When you have a program like that, the solution is to rewrite the code so that it's clear who is responsible for signaling "nothing more will be sent on this channel" and when. The solution is not to paper over it with new operators.

@golang golang locked and limited conversation to collaborators Jan 5, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.