closing channels

111 views
Skip to first unread message

yy

unread,
Mar 9, 2011, 2:30:43 PM3/9/11
to golang-nuts
The original rsc's proposal to modify channels [1] consisted of three
steps. The main idea behind this proposal was that only a sender
should close a channel and only a receiver should check that it was
closed. The final result will be that the closed() builtin will
disappear and will be replaced by v, ok <- c, where ok is false if the
channel was closed.

I would like to propose to add a fourth step to this plan to remove
the close builtin too. Instead, we could close channels with c <- v,
false. This is analogous to deletion from maps and have the added
benefit that, then, only the sender would be allowed to close
channels. It could even be more useful than close() if c <- v, false
meant that, from now on, the channel will always return v, instead of
the zero value, although I'm not sure this is a good idea.

Of course, this would have to wait until the other changes are in but,
do you think it would be a logical next step?


[1] http://groups.google.com/group/golang-dev/browse_thread/thread/54afcbe71d448012/#msg_4e737a923eb2cc01

--
- yiyus || JGL .

Sam Fredrickson

unread,
Mar 9, 2011, 3:53:37 PM3/9/11
to golang-nuts
Additionally, it should be possible to write that as "c <- _, false"
so that you don't have to declare some unused variable just for
closing.
> [1]http://groups.google.com/group/golang-dev/browse_thread/thread/54afcb...

David Symonds

unread,
Mar 9, 2011, 3:57:58 PM3/9/11
to yy, golang-nuts
I don't think it's a good idea.

The "closed" builtin function is going away because it's too easy to
misuse it (e.g. from the sender's side). Your proposal is not removing
the "close" functionality, only turning it from a builtin function to
a remarkably subtle operator operation.

Arguably the syntax for deleting from maps is also obscure; if
anything that should be the one to get changed.


Dave.

John Asmuth

unread,
Mar 9, 2011, 4:41:21 PM3/9/11
to golang-nuts
What about "c <- _, ShouldIClose()"? Having a special case for _,
false doesn't make a lot of sense to me, when we already have
close(c).

yy

unread,
Mar 9, 2011, 6:33:05 PM3/9/11
to David Symonds, golang-nuts
2011/3/9 David Symonds <dsym...@golang.org>:

> Arguably the syntax for deleting from maps is also obscure; if
> anything that should be the one to get changed.

This has been discussed before:
http://groups.google.com/group/golang-nuts/browse_thread/thread/55758d25014282db/
I think that the same reasons given to delete from maps with a
comma-false assigment apply to closing channels sending v, false.
Since it is simmetrical to receiving from a channel, I don't think is
too subtle. rsc wrote about maps:

"If you know about x, ok = m[k] and what it means for ok to be false,
then m[k] = x, false should be plenty clear."

s/= m[k]/= <- c/
s/m[k] =/c <-/

In fact, almost everything in that thread would apply here (for
example, the possible use of the blank identifier as the zero value).

David Symonds

unread,
Mar 9, 2011, 6:40:52 PM3/9/11
to yy, golang-nuts
On Wed, Mar 9, 2011 at 3:33 PM, yy <yiyu...@gmail.com> wrote:

> I think that the same reasons given to delete from maps with a
> comma-false assigment apply to closing channels sending v, false.
> Since it is simmetrical to receiving from a channel, I don't think is
> too subtle.

Closing a channel is not symmetric to receiving on a channel.
Closing a channel, if anything, is symmetric to opening a channel,
which you do with the "make" function.


Dave.

Andrew Gerrand

unread,
Mar 9, 2011, 6:40:38 PM3/9/11
to yy, David Symonds, golang-nuts
On 10 March 2011 10:33, yy <yiyu...@gmail.com> wrote:
> I think that the same reasons given to delete from maps with a
> comma-false assigment apply to closing channels sending v, false.
> Since it is simmetrical to receiving from a channel, I don't think is
> too subtle.

Assigning to a map and deleting from a map are exclusive operations.
You can be either assigning or deleting, but not both. The map
deletion syntax is clear, if a little weird.

Closing and sending to a channel are orthogonal operations. You can
close, send, or close and send. The proposed syntax doesn't make it
clear what is happening, exactly.

Andrew

yy

unread,
Mar 9, 2011, 7:12:36 PM3/9/11
to Andrew Gerrand, David Symonds, golang-nuts
2011/3/10 Andrew Gerrand <a...@golang.org>:

> Closing and sending to a channel are orthogonal operations. You can
> close, send, or close and send. The proposed syntax doesn't make it
> clear what is happening, exactly.
>
> Andrew
>

I don't understand this. Either you send to a channel or you close it,
but how do you close and send?

Maybe what you mean is that c <- v, false can mean two different
things: first send v, then close the channel, or just close the
channel. What I propose is that what you send is what you will
receive. If you send false as second value the next receive operation
has to get false, so the channel has to be closed and the value can be
discarded.

I agree that having a dummy value there can be confusing, that is why
I suggested to return that value instead of the zero value. Then, the
rule would be very simple and clear: after sending v, false to a
channel (and all the previous values have been received) every receive
operation will get v, false without blocking and any send operation
will panic.

Russ Cox

unread,
Mar 9, 2011, 9:41:19 PM3/9/11
to yy, Andrew Gerrand, David Symonds, golang-nuts
There's a parallel here but it's a weak one,
and I don't think it makes code closing channels
any more readable or useful.

Russ

Hoka Admin

unread,
Mar 10, 2011, 6:17:19 AM3/10/11
to r...@golang.org, yy, Andrew Gerrand, David Symonds, golang-nuts

On 9 Mar 2011 19:30, "yy" <yiyu...@gmail.com> wrote:
>
> The final result will be that the closed() builtin will
> disappear and will be replaced by v, ok <- c, where ok is false if the
> channel was closed.
>

It's quite rare that I've used a non-blocking read from a chan, in fact I think it was only to test the syntax, but I thought that : 

  v, ok := <- c

Was a "non blocking" read from the channel.

How would that work with your proposed :

  v, ok <- c

To check on the receiver if the channel has been closed by the sender, assuming you also use a non blocking read?

Personally, I'm quite happy with close / closed.


yy

unread,
Mar 10, 2011, 6:23:59 AM3/10/11
to Hoka Admin, r...@golang.org, Andrew Gerrand, David Symonds, golang-nuts
2011/3/10 Hoka Admin <ho...@hokapoka.com>:

> On 9 Mar 2011 19:30, "yy" <yiyu...@gmail.com> wrote:
>>
>> The final result will be that the closed() builtin will
>> disappear and will be replaced by v, ok <- c, where ok is false if the
>> channel was closed.
>>
>
> It's quite rare that I've used a non-blocking read from a chan, in fact I
> think it was only to test the syntax, but I thought that :
>
>   v, ok := <- c
>
> Was a "non blocking" read from the channel.
>
> How would that work with your proposed :
>
>   v, ok <- c
>

This was a typo, sorry. I meant:

v, ok := <- c

Non blocking operations have to be done adding a default case to
select now. Using comma-ok to indicate if the channel is closed and
removing the closed() builtin is a planned change to the language
which has not been done yet. See the thread I referenced in my first
post on this thread, where the plan is fully explained.

yy

unread,
Mar 10, 2011, 6:26:28 AM3/10/11
to r...@golang.org, Andrew Gerrand, David Symonds, golang-nuts
2011/3/10 Russ Cox <r...@golang.org>:

The real reason I proposed this change is because it limits channel
closing to senders. The parallelism with deletion from maps is just a
happy coincidence, and a precedent for a similar syntax.

Maybe limiting the check for closed to receivers (as is planned) is
enough to avoid miss-usage, but even then people could close a channel
from the receiver and recover from a panic in the sender if it was
closed. If that became a new pattern (let's hope not), removing
close() could be a way to avoid it (another one is to not allow using
close() on a channel you cannot send to).

Is there any reason I'm missing to let receivers to close a channel?
Making channel closing a special send operation looks to me like a
reasonable way to enforce the idea that the sender is the responsible
of closing.

Other benefits of the <- v, false syntax are that it removes a builtin
(close is an useful name) and that it can simplify some code when you
close or send depending on a condition, as in:

v, err = fn()
c <- v, err == nil

However, I'm not sure this is very common (after a very quick search,
I did not see anywhere in the library where it could be directly
applied).

I don't think any of these reasons is enough to justify a change on
their own, but maybe they are when put together. Anyway, I think the
most sensible thing to do, for the moment, is to wait and see how the
changes to receive operations work.

roger peppe

unread,
Mar 10, 2011, 6:44:11 AM3/10/11
to yy, r...@golang.org, Andrew Gerrand, David Symonds, golang-nuts
On 10 March 2011 11:26, yy <yiyu...@gmail.com> wrote:
> 2011/3/10 Russ Cox <r...@golang.org>:
>> There's a parallel here but it's a weak one,
>> and I don't think it makes code closing channels
>> any more readable or useful.
>>
>> Russ
>>
>
> The real reason I proposed this change is because it limits channel
> closing to senders.

that would be easy to do by making it illegal to call close
on a receive-only channel. i think that should probably
happen anyway, but others probably have a different opinion.
have any of you found a legitimate use for closing a receive-only
channel?

Russ Cox

unread,
Mar 11, 2011, 10:05:07 AM3/11/11
to roger peppe, yy, Andrew Gerrand, David Symonds, golang-nuts
> that would be easy to do by making it illegal to call close
> on a receive-only channel. i think that should probably
> happen anyway, but others probably have a different opinion.
> have any of you found a legitimate use for closing a receive-only
> channel?

there is no legitimate use, by definition.
the use of directionally typed channels is not very
common in go programs so restricting close would
not have much practical effect but it might be
worth considering.

russ

roger peppe

unread,
Mar 11, 2011, 10:18:42 AM3/11/11
to r...@golang.org, yy, Andrew Gerrand, David Symonds, golang-nuts

it's not that uncommon in libraries. for instance the channel
in a time.Ticker is receive-only.

it would also be an instant warning of misuse - i've seen
people do this when they haven't quite grasped how
channels are supposed to be used.

Reply all
Reply to author
Forward
0 new messages