I was planning to read the updated proposal in more details before replying, but I haven't been able to find the time sadly, so I'm doing it anyway :), mostly inline. There are a couple of general points I'd like to put forward first.
- What I'm trying to push towards is not my particular approach, but more simplicity while retaining enough usefulness (that is, being a good fit for the established good use cases for generics in Go). I think that when you explore how to introduce generics into Go, it's important to remember how effective it has been without generics (and partly because of its lack of generics), and to try not to upset that balance. - There is one aspect of the current proposal that makes me think that we can find a better manifestation of generics in Go. To take the one of the simplest examples, the Stringer example: type Stringer interface { String() string } Here is the generic Stringify implementation func Stringify(type T Stringer)(s []T) (ret []string) { for _, v := range s { ret = append(ret, v.String()) } return ret } Here is the "plain" non-generic one func Stringify(s []Stringer) (ret []string) { for _, v := range s { ret = append(ret, v.String()) } return ret } The two implementations above express the same intent, even have the same body, but they are not the same thing! Obviously you can use Stringify(Stringer) to obtain the second one from the first but to me it feels like we are missing a trick, a better perspective that would make this simplest of examples more natural. - shortly after the contracts proposal was published, I found that I was unhappy with the overlap between contracts and interfaces, wrote an explanation of the problem and imagined a rebalancing of the proposal which is in essence the new one (ie. interfaces can be generic). I think it's useful because it presents a rationale for "transforming" the earlier contracts proposal into the new interface-based one, so I've posted it here: https://arnodel.github.io/marooned/go/generics/2020/06/21/go-against-contracts.html Kind regards, Arnaud Delobelle On Wednesday, 17 June 2020 at 06:10:08 UTC+1 Ian Lance Taylor wrote: > On Tue, Jun 16, 2020 at 1:54 PM Arnaud Delobelle > <arnaud.d...@sparx.co.uk> wrote: > > > > I noticed today the blog post about the revised Generics proposal. What > got me excited is this extract at the start: > > > > The biggest change is that we are dropping the idea of contracts. The > difference between contracts and interface types was confusing, so we’re > eliminating that difference. > > > > To me the lack of orthogonality between contracts and interfaces was the > major issue with the previous proposal and I have been musing with ways of > resolving it for a while, so I am very pleased that the proposal is going > down this path! > > > > Last month I decided to write a post about a way of introducing Generics > into Go using interfaces, which I called "Package Specialization". > > > > Headline features are: > > > > use interfaces to express parametric types; > > no new keyword; > > the only new syntax is “package specialization”: pkg(T=int, > Y=*MyType).Func(); > > generic code which doesn’t use the package specialization syntax is > already valid Go. > > > > The full post can be read here: > https://arnodel.github.io/marooned/go/generics/2020/06/06/go-spec2.html > > > > I was toying with the idea of submitting it here for feedback, to try to > move the discussion in that direction. Well, I guess today's updated > proposal steals my thunder! Essentially this is the same idea, but with a > different manifestation in the language - I thought that submitting it > anyway may provide a useful comparison point to help gauge the updated > proposal better. > > > > Note that sadly, I do not have much time to polish a proposal or to > follow discussions in general on this or other golang-related discussion > lists, so I apologize in advance if I am inadvertently re-hashing ideas > that have been put forward and dismissed in the past, or if my blog post is > a little low on detail (it was meant to be an exploration of a possible > approach). > > Thanks. I hadn't seen that before. > > A difficulty with package specialization is when you want to write a > List(List(int)). That is, a List where each element of the List is a > List(int). That would be list(T = list(T = int).List).List, which I agree is not the most palatable. Of course one could defined an intermediary type type intList = list(T = int).List > Or, when you want to write a transformation function as in > > https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md#list-transform. > > > I guess to do it literally you would do something like this. package transform type T1 interface {} type T2 interface {} func Transform(lst *list(T1).List, f func(T1) T2) *list(T2).List { ret := &list(T2){} it := lst.Range() for { if v, ok := it.Val(); ok { ret.Push(f(v)) } if !it.Next() { break } } return ret } To me it becomes apparent that it's not the right way of doing this though as the implementation of Transform doesn't really depend on the fact that we are dealing with lists, instead it relies solely on the iteration interface for the source and the "pushing" interface for the destination. So I'd probably have it as something like: --- transform/transform.go --- package transform type T1 interface{} type T2 interface{} type S interface { Next() bool Val() (T1, bool) } type D interface { Push(T2) } func Transform(src S, f func(T1) T2, dst D) { for { if v, ok := src.Val(); ok { dst.Push(v) } if !src.Next() { return } } } --- main.go --- // l1 is a list of ints l2 := &list(float64).List{} transform(...).Transform(l1.Range(), l2, func(n int) float64 { return float64(n)}) That transform package doesn't require special generic syntax to be written (or understood), and I guess that was part of my aim. It would seem to require some modification of how imports work in Go, > and that leads into considerable complexity. See also > . > https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md#why-not-put-type-parameters-on-packages > > I must admit that although I do know how imports work in Go, I don't know anything about how they are implemented. I did try to think this through though and outlined a way to understand the semantics of specialized packages, which I thought was acceptable. To me there are also interesting questions about importing "generic entities" and specializing them with the same types in different packages under the current proposal (but I haven't been able to verify what the proposed solution to these issues are). > . > > 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/87caf8c4-1523-48f2-8d3f-0b5fe6c5361cn%40googlegroups.com.