On Thu, Jul 2, 2020 at 4:59 PM ben...@gmail.com <benh...@gmail.com> wrote: > > This thread on lobste.rs made me wonder if the difference between type-list > constraints and method-interface constraints is going to cause a bunch of > issues or code duplication. There's a lack of orthogonality here that makes > me uneasy. > > For example, the Smallest() function in this proposal takes a slice of []T, > where T is "type T constraints.Ordered", a type-list based constraint. That > means Smallest() will only work with the built-in types specified in the type > list (or types with one of those as an underlying type), and can't be used > with more complex struct types. > > For it to work for other types, you'd have to write a second version of > Smallest() -- code duplication -- that took a method-interface based > constraint like so: > > type CustomOrdered(type T) interface { > Less(other T) bool > } > > Arguably Smallest() would still be quite useful even if it only works for > builtin integer and float point types, but with the type-list Ordered it > wouldn't work for (say) big.Int, a custom Decimal type, or a more complex > struct type. > > But I think this is worse for ordering-based *data structures* like Tree of > T. If done with the type-list Ordered, the tree could only store built-in > types, which isn't that useful. Using a constraint like CustomOrdered would > work and be more flexible ... but then a basic Tree(int) wouldn't work. You'd > have to do Tree(MyInt) and convert everything from int to MyInt on the way > in, and MyInt back to int on the way out -- a bunch of type conversion > boilerplate. > > Or you'd end up writing two versions of your generic Tree: BuiltinTree that > uses Ordered (type lists), and CustomTree that uses CustomOrdered (interface > with Less). Not very nice. > > (Here's some Go2Go code which shows this for Smallest: > https://go2goplay.golang.org/p/Rbs374BqPWw) > > I'm not sure how the proposal solves this for something like Smallest() ... I > don't think it does. For ordered data structures, like the Map example, it > passes in a custom "compare" function to the initializer and kind of > side-steps the issue. Which isn't bad for data structures as it'd still > eliminate a lot of code, but it would be kind of a pain for little algorithms > like Smallest(). > > Thoughts?
What you say is true. I don't know of a way around the basic problem other than introducing methods on basic types. That would be a big change to the language, and would require introducing a large number of new names. The way I would suggest handling your Tree example is by making the basic data structure take a comparison function. Then you can write tiny wrappers that create the function for any ordered type, or for any type with a Less method. Or people can just pass their own comparison function. You suggest that the Map example sidesteps the issue by using a comparison function, which is true, but the Map data structure is also more flexible with a comparison function. For example, it lets you store the same type in multiple types with different sorting. The Smallest example is a case where we don't need to store the value, so you can take an approach like the sort example in the design draft (https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md#sort). I'm not going to claim that these are perfect solutions, but they seem workable to me. It would be interesting to hear of real cases where they are problematic. Ian -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAOyqgcXH9oMLS-0yJeZYmOP3S3vPhDS-17w9oz21ACnD%3DADBvw%40mail.gmail.com.