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
slices: add iterator-related functions #61899
Comments
Concat takes a a variadic second arg #56353 |
@rsc – Any reason why |
I think this makes sense here. The iters package would define the iter.Iter type and things like Map, Filter, TakeWhile, and Zip that don't deal with particular iterator sources. You import slices when you want to convert an iter.Iter to/from a slice, and e.g. maps.Keys when you want to iterate over a map. |
// Better name pending.
func SecondRet[T1, T2 any](iter Seq2[T1, T2]) Seq[T2] {
return func(yield func(T2) bool) {
for _, v := range iter {
if !yield(v) {
return false
}
}
}
} Either that or Also, two more functions that I'd like to suggest: // SortInto places the elements of iter into the already sorted slice dst, expanding as necessary, and returns the resulting slice, also sorted.
func SortInto[S ~[]E, E cmp.Ordered](dst S, seq Seq[E]) S
func SortIntoFunc[S ~[]E, E any](dst S, seq Seq, cmp func(E, E) int) And |
This proposal has been added to the active column of the proposals project |
I’m a little nervous looking at this that someone is going to immediately release a fluent API for these which will be preferred by the community, and STL will be left with a less used package. E.g
and so on. Maybe it’s ok if that ends up happening, but seems a bit sad. |
That’s both comforting and distressing :) |
Please add syntax highlighting to your code blocks. With it, you might have noticed that Sorted should be SortedFunc here: // SortedFunc collects values from seq into a new slice, sorts the slice, and returns it.
func Sorted[Elem any](seq iter.Seq[Elem], cmp func(Elem, Elem) int) []Elem { It seems like the functions that return iter types should be in the iter package, so they can be grouped under the Seq/Seq2 types in the generated documentation. These are technically "constructors" for those types in that sense. The functions that take iter types also seem like they belong in iter, as utility functions that work on iter types. I'm reminded of the io package, which declares Reader and various functions that produce and consume Readers. Slices are built into the language, so it doesn't seem like a function producing or consuming a slice alone warrants it being in the slices package. The new go/token.File.Lines method returns a slice, yet I doubt it was ever considered whether it belonged in the slices package (being a method aside). |
I dont mind the colorless code blocks. The tone there also seems a bit rude @willfaught |
My apologies. |
In most language, the func Iter[E any](slice []E) iter.Seq[E] {
...
}
// and for enumerate
func Enumerate[E any](slice []E) iter.Seq2[int, E] {
// or if we had tuple type, return should be iter.Seq[(int, E)]
// Again, I personally think that Seq2 is a very unwise design
...
} |
I think you're forgetting the context. The function isn't |
I had not paid close attention to the names of the functions this proposal wants to add so far. In #61626 (comment), @rsc gives an example use as follows.
Somehow knowing that I think that my initial confusion when reading the call site without having invested in already knowing the details of the |
@ChrisHines I think it's fairly common for a function to be named after what it returns and what it does, but less so after what it takes. There is also precedence: In python, To me, this seems fine. |
Besides Python, JavaScript has Array.toSorted which returns a new Array that was sorted. So, two languages at least where "sort" means in place and "sorted" means "new slice/list/array". |
Does Sorted need a stable variant? It does seem unfortunate to have so many sort variants:
cc @eliben |
Python's |
func Sorted[Elem comparable](seq iter.Seq[Elem]) []Elem {
slice := Collect(seq)
Sort(slice)
return slice
} I'm not a sorting expert, but I'm curious if using an online sorting algorithm here could be an improvement. There could be delays between iterations. |
The heap package is in need of a total overhaul. It could incorporate iterators if that happened. |
Maybe slices.SortedFunc should be stable by default. Anyone who wants a faster sort can write it manually, and stability bugs are more likely to matter in production than minor performance hits. |
Finishing this proposal discussion is blocked on #61405. |
Change https://go.dev/cl/558737 mentions this issue: |
Given slices.SortFunc exists and is unstable, it would be inconsistent for slices.SortedFunc to be stable. It would be especially annoying when moving between the two that the semantics change. If you replace a use of a stable SortedFunc with an unstable SortFunc, you'd be sad. Given that slices.SortStableFunc exists, we should probably also add slices.SortedStableFunc to complete the set, so people don't have to remember which exist and which don't. |
Have all remaining concerns about this proposal been addressed?
|
When I look at the list today, I'm a little worried about |
|
|
Or |
I don't think that naming is the problem, but rather the fact that we have two different ways of doing the exact same thing (namely, appending to a slice). Besides, if people see an I think that the bigger issue is that before this, appending to a slice was a no brainer: To me personally, the most natural thing would be for |
Does this append the iter.Seq itself or its elements?
You'd need a |
My counter-argument to changing So I don't really see a satisfying way to retro-fit Personally, I think |
Yes, I stand corrected, modifying Having I apologize for the noise. |
I personally think having Iter.Seq work as a variadic argument with “…” would actually make the most sense and would cement it alongside all the other natural types that represent a sequence of values in the language.As for the cost, yes there is one, but I don’t think it’s higher than the one incurred by inconsistency.On Feb 12, 2024, at 5:35 AM, Alexandru Ungur ***@***.***> wrote:
Yes, I stand corrected, modifying append is not really what I was looking for, just having append(s, slices.Collect(iter.Seq)...) work, the append(s, iter.Seq) should do the appending of iter.Seq to a []iter.Seq as expected. No extra magic or anything like that.
Having slices.Append() also do that, more succinctly, doesn't really bother me (and since it appends, it may as well be called that, I don't see a need to look for variations of the name "append").
I apologize for the noise.
—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you commented.Message ID: ***@***.***>
|
The case of |
AppendSeq sounds fine; good point about confusion with builtin append. |
Based on the discussion above, this proposal seems like a likely accept.
|
No change in consensus, so accepted. 🎉
|
Change https://go.dev/cl/568477 mentions this issue: |
I suspect there is a typo in the API above. |
We propose to add the following functions to package slices, to provide good support for code using iterators.
This is one of a collection of proposals updating the standard library for the new 'range over function' feature (#61405). It would only be accepted if that proposal is accepted. See #61897 for a list of related proposals.
All serves as a “source” for iterators.
Backward can be used to replace existing 3-clause loops that iterate backward over a slice manually. This happens fairly often in certain algorithms (for example it happens a lot in the compiler’s SSA code).
Values is like All: not terribly useful by itself but useful as a source for other code.
Append and Collect serve as “sinks” for iterators.
Sorted and SortedFunc collect an iterator and then sort the contents:
The text was updated successfully, but these errors were encountered: