-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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: chans: new package with chans.Seq #67205
Comments
I have a package that implements a bunch of iterator-related stuff so that I can play around with it. To supplement the simpler |
chans.Seq seems definitely necessary. I was thinking we might also want the reverse, which would be like SendContext minus the context part. Putting it together, maybe it should be these four functions to start with: func Seq[T any](<-chan T) iter.Seq[T]
func SeqContext[T any](context.Context, <-chan T) iter.Seq[T]
func FromSeq[T any](iter.Seq[T]) <-chan T
func FromSeqContext[T any](context.Context, iter.Seq[T]) <-chan T There was also talk about having helpers like FanIn and FanOut back when generics were still experimental, but those can be a separate proposal. |
func FromSeq[T any](iter.Seq[T], chan<- T) rather than returning a channel. |
That makes sense. You can reuse an existing channel and you get better type inference. |
Other names for chans.FromSeq[Context] might be chans.Send or chans.Copy. |
For the two variants that take a I'm accustomed to seeing functions that take a context return an error because an operation being cancelled (or, equivalently, hitting a deadline) is usually modeled as a kind of failure. These functions don't do that, and of course they cannot because the current iterator design only supports infallible iterators. I can imagine having the caller use s := slices.Collect(chans.SeqContext(ctx, ch))
if ctx.Err() != nil {
// s may not be complete, then
} Overall this reminds me of the Overall I don't feel super worried about either of these details myself. They certainly don't seem disqualifying, and I raise them largely just for the sake of discussion. (The non-context versions seem uncontroversial to me; they are pretty obvious implications of the iterators design.) |
You could have |
|
Just a note that the main reason I haven't proposed a chans package is exactly the question of how to handle contexts. |
How about treating contexts like log/slog did? That would be most consistent and easy to teach. |
Where
Where contexts are used elsewhere in the standard library tends to be domain-specific: There's undoubtedly a useful notion of cancellation here with |
To get around having a dependency on context, there could be variants that take |
func Seq[T, Done any](ch <-chan T, done <-chan Done) iter.Seq[T] {
return func(yield func(T) bool) {
for {
select {
case v, ok := <-ch:
if !ok {
return
}
if !yield(v) {
return
}
case <-done:
return
}
}
}
}
func Count() <-chan int { /*...*/ }
func main() {
for n := range Seq(Count(), time.After(1*time.Microsecond)) {
fmt.Println(n)
}
} Interestingly, this works in a real program but it times out on Playground, presumably because Playground time is an illusion. |
This is my favorite proposal. What are the arguments against it? |
Proposal Details
#61899 would add iteration related functions to slices, and #61900 does the same for maps. There should also be a package with channel iteration helpers. I propose adding package chans with chans.Seq:
An example use would be
s := slices.Collect(chans.Seq(ch))
as a convenient way to collect all values from a channel into a slice.The text was updated successfully, but these errors were encountered: