proposal: container/set: new package to provide a generic set type (discussion) #47331
Replies: 45 comments 352 replies
-
Needs some sort of performance promise. I think it would be ok to promise that |
Beta Was this translation helpful? Give feedback.
-
Regarding the naming, it seems inconsistent to me to have standalone functions named |
Beta Was this translation helpful? Give feedback.
-
I don't understand this argument (also, IMO there should just be one function |
Beta Was this translation helpful? Give feedback.
-
I find it awkward to say "Like maps, Sets are reference types" and having to explain that, instead of just making it a pointer. It might feel weird to always have to pass around a |
Beta Was this translation helpful? Give feedback.
-
Any reason why Union, Intersection and Difference are functions instead of methods? image.Rectangle has Union, Intersect and other binary operations as methods, image.Point and the types in math/big as well. Methods would feel more like infix notation. My suggestion would be Set[Elem].Union, Set[Elem].Intersect, Set[Elem].Diff |
Beta Was this translation helpful? Give feedback.
-
Why the requirement not to modify the set during iteration? Maps don't have that requirement and that's a very helpful property. Also, iterating by using a function is awkward (you can't just return from the outer function, or break more than one level of loop), so I wonder if it might be nicer to support some kind of iterator so iteration can be done with a straightforward |
Beta Was this translation helpful? Give feedback.
-
"Len" is an unusual name for the cardinality of a set, the colloquial term is usually "Size". Of course, "Len" would fit the Len method in sort.Interface (but the proposed Set type can't be sorted), and other types are measured via the "len" builtin function, so that's probably where it comes from. |
Beta Was this translation helpful? Give feedback.
-
Can we get explicit promises for the iteration order? And maybe another |
Beta Was this translation helpful? Give feedback.
-
Making |
Beta Was this translation helpful? Give feedback.
-
I would expect |
Beta Was this translation helpful? Give feedback.
-
This proposal uses |
Beta Was this translation helpful? Give feedback.
This comment has been minimized.
This comment has been minimized.
-
In functional programming, Personally, I like |
Beta Was this translation helpful? Give feedback.
-
Parallel to #47330 (comment) for |
Beta Was this translation helpful? Give feedback.
-
In Java, it is often annoying that the various container types' |
Beta Was this translation helpful? Give feedback.
-
I think the doc comment can be reduced to:
Calling sets "reference types" is confusing because they're not, at least as currently documented. They're just structs that happen to hold pointers, which is true of most Go types. We don't refer to them all as reference types. Calling out that Sets cannot be modified concurrently from multiple goroutines is also confusing, because that's the default expectation for every Go data structure. We only document the deviations, when concurrent modifications are allowed. (Compare list.List: it is just as much a "reference type" and is similarly safe to read but unsafe to modify from multiple goroutines, but we don't call attention to any of that. Or bytes.Buffer, which is also just as much a "reference type".) Mentioning maps also encourages the reader to start thinking about questions like why isn't this a map or exactly how maps work. It is probably better to just let Sets be Sets. |
Beta Was this translation helpful? Give feedback.
-
The type Set[Elem comparable] struct {
// contains filtered or unexported fields
}
// Values returns the elements in the set s as a slice.
// The values will be in an indeterminate order.
func (s *Set[Elem]) Values() []Elem
// Do calls f on every element in the set s,
// stopping if f returns false.
// f should not change s.
// f will be called on values in an indeterminate order.
func (s *Set[Elem]) Do(f func(Elem) bool) I see two approaches to iteration given the current API:
Could we include in this proposal a method of iterating |
Beta Was this translation helpful? Give feedback.
-
[Edit: this turns about to be confusion over naming rather than a problem with the API signature itself.] The lack of a short-circuit mechanism for The corresponding It is clearly possible to write every |
Beta Was this translation helpful? Give feedback.
-
Retracted I think something that may be concerning is that because this is implemented using a map, this would mean that sets are not comparable. So, a Set of Sets is illegal. However, I'm not exactly sure how we could implement sets such that a set of sets would be useful, other than abandoning the |
Beta Was this translation helpful? Give feedback.
-
FWIW in Java the collection will often cache the hash and invalidate when the collection is modified making many uses more efficient than they might be thought of.
… On Sep 3, 2021, at 10:52 AM, Dean Bassett ***@***.***> wrote:
It's theoretically possible to build variable sized data structures which are comparable. Theoretically, it might be possible to extend this technique to a reasonably efficient comparable set data-structure (probably not with O(1) access time, but maybe O(log(n))).
That's a really neat example. I wouldn't really say that the example "isn't Go-like" (I wouldn't mind seeing this as a third-party library), but I agree that something like this shouldn't be the standard implementation or even exist in the standard library. However I would love to use something like this to convert a set into an immutable set, then use that to make a set of sets. Going to retract this.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.
|
Beta Was this translation helpful? Give feedback.
-
Maybe this is a nitpick, but Is there any appetite for the verb forms of |
Beta Was this translation helpful? Give feedback.
-
Is it actually possible to implement this behaviour with usable zero values? Consider the following two code fragments: var a, b set.Set[int]
a.Add(1)
b = a
b.Add(2) and: var a, b set.Set[int]
b = a
a.Add(1)
b.Add(2) If sets really are reference types, then it shouldn't matter when I perform the assignment. But if the set is in its uninitialised state when I perform the assignment, there's no internal pointer to copy over linking the two variables. If the implementation of |
Beta Was this translation helpful? Give feedback.
-
I don't see that it has been suggested yet, so I will:
This makes sense if we agree that an array is the only/most reasonable way to encode a set into JSON, and if we want the set types, like the PS! This thread should be about JSON encoding support only. I think XML, sql etc. should be discussed (and probably rejected) in separate threads. |
Beta Was this translation helpful? Give feedback.
-
Is this still planned for Go 1.19 release? |
Beta Was this translation helpful? Give feedback.
-
Perhaps there should be a variant of the constructor to make a map with a given capacity. Might be useful in situations like:
|
Beta Was this translation helpful? Give feedback.
-
Set.Grow() and Set.Shrink() are not great interface methods. It leaks implementation details and offers semantics that may not be applicable. Better to add these to a ResizableSet interface or similar. |
Beta Was this translation helpful? Give feedback.
-
What is the rationale for IMO it could be more appropriate for a method with pointer receiver type to return a pointer to the value or non-pointer receiver type to return a non-pointer value -- so that both could pass a |
Beta Was this translation helpful? Give feedback.
-
I am not sure if this has been mentioned but how will range adapt to an ordered set? How will a user be able to know if the set being iterated over is ordered? if the an interface is passed to functions it implies we need additional marker methods (e.g IsOrdered) for the consumer. |
Beta Was this translation helpful? Give feedback.
-
How do I avoid the cost of an ordered set when I only need an unordered set? Ordering seems to be a quality of a given implementation - much like three safety (built in synchronization or lack thereof). |
Beta Was this translation helpful? Give feedback.
-
map[T]bool or map[T]struct{} are already familiar and working ways of implementing a generic set. Also, the implementation indicated in this proposal is map[T]struct{}. What then are the pros for hiding this within a struct in container/set, instead of just making generic functions that operate on such a map and methods on a generic derived type (type Set[T comparable] map[T]struct{} )? The maps and slices proposals do it like this I think. In particular, the maps proposal is so close to such a set, that many functions are identical (Clear, Equal, Filter is maps.DeleteFunc, and Values is maps.Keys). Exposing the map[T], would immediately remove all the questions about complexity guarantees, and let us defer the iterator interface discussion as range already works directly on maps. |
Beta Was this translation helpful? Give feedback.
-
This is a discussion that is intended to turn into a proposal.
This proposal is for use with #43651. We propose defining a new package, container/set, that will introduce a new set type.
It is possible that this proposal, if accepted, will be included with the first release of Go that implements #43651 (we currently expect that that will be Go 1.18). Or it may be appropriate to delay this package until a later release.This package will not be in the 1.18 release, but is for consideration for a later release.This description below is focused on the API, not the implementation. In general the implementation will be straightforward.
See also the slices proposal at #45955 (discussion at #47203) and the maps proposal discussion at #47330.
Beta Was this translation helpful? Give feedback.
All reactions