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][email protected].
> 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:[email protected]
> 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 [email protected].
For more options, visit https://groups.google.com/d/optout.