I don't think you even need contracts as such at this point; you can do a cast without them, so you just need to be able to specify a method set on type parameters. I would be interested to hear your thoughts on the proposal I wrote up on how to do this:
https://gist.github.com/zenhack/ad508d08c72fce6df945a49945ad826d what you're suggesting below lands in a similar spot, though the change in rules around casting makes it a big more ergonomic. But my version doesn't introduce a separate contract construct at all; it just uses interfaces to specify bounds. When I wrote that I described the lack of being able to deal with operators as "unsatisfying," but outlined that you could do something similar to what you describe, and said I preferred that to introducing a non-orthogonal construct to the language. Part of why I left out operators was because of the issue with == that I mentioned earlier, though ESR has offered a possible solution. -Ian Quoting roger peppe (2018-10-17 12:43:44) > While thinking about the draft generics proposal and the complexity of > contracts, it occured to me that if you relax some of the restrictions > on type conversion, it's possible to make data structures containing > basic types amenable to generic algorithms. > Once upon a time, the Go specification [1]allowed conversion between > any two values with with same underlying types. You could, for example, > convert from []int to []time.Month. This� [2]was changed� after [3]some > discussion. > As a thought experiment, suppose that rule change was reverted and > generics were implemented similarly to the draft proposal, but with > contracts that allowed type conversions only, and no other operators. > That allows the possibility of "retro-fitting" methods to data > structures containing basic data types. > For example, given this generic interface definition: > � � type Adder(type T) interface { > � � � � Add(t T) T > � � } > and a generic Sum function: > � � contract Adder(t T) { > � � � � Adder(T)(t) > � � } > � � func Sum(type T Adder)(xs []T) T { > � � � � var sum T > � � � � for _, x := range xs { > � � � � � � sum = sum.Add(x) > � � � � } > � � � � return sum > � � } > We can make Sum work on []int like this: > � � type Int int > � � func (i Int) Add(j Int) Int { > � � � � return i� + j > � � } > � � func main() { > � � � � ints := []int{3,5,6,7} > � � � � sum := Sum([]Int(ints)) > � � � � fmt.Println(sum) > � � } > One could imagine a new package in the stdlib that provided method > definitions for all the basic types, and potentially standard > interfaces too. But there would be no need to define any of that in the > language specification. The need for arbitrary operators in contracts > goes away. All generic code can be used with custom types with custom > behaviour for the operators, because all operations are expressed with > methods. This provides a clean separation between generic operations > (they always look like method calls, whether using interfaces or type > parameters) and built-in operators. The method calls in question can be > inlined because everything is known statically, so there's > theoretically zero performance overhead. > Generic functions that would previously have been able to use operators > don't look as nice, of course, but maybe that's a price worth paying. > Unfortunately this idea doesn't work very well because of a few > reasons. Firstly. anything that is returned by a generic function still > has the converted type. So the sum variable in main above has type Int, > not int. Also, if one is converting to other types as a matter of > course, one loses the type safety that comes with using different > types. > That said, maybe there's a glimmer of possibility here. You get a lot > of potential for a very small language change, so I'm throwing out this > idea in case someone has a good idea how to circumvent the > above-mentioned problems. > > -- > 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 [4]golang-nuts+unsubscr...@googlegroups.com. > For more options, visit [5]https://groups.google.com/d/optout. > > Verweise > > 1. > https://github.com/golang/go/blob/67d30bb696fd28477ec023926b0ead375cf8371e/doc/go_spec.html#L1238-L1242 > 2. > https://github.com/golang/go/commit/63f014910daab38faee6208de2cbdbc191985d8c > 3. https://github.com/golang/go/issues/809 > 4. mailto:golang-nuts+unsubscr...@googlegroups.com > 5. https://groups.google.com/d/optout -- 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. For more options, visit https://groups.google.com/d/optout.