Hi Patrick, I guess it's largely a matter of taste but one of the reasons why I prefer contracts to interfaces is precisely because you only need one contract for the type parameters as a whole.
This keeps the type parameter section of the generic function/type relatively brief when you have more than one parameter as well as tying things together when you have mutually referential parameters. Even if a contract could only refer to a single parameter, I'm also not keen on using the contract name for that parameter which I think would be relatively verbose. This is because the contract could have a longish name whereas type parameters typically have short names, often a single upper case letter. I'm pleased you liked the simplified syntax for the contract body though :) Alan On Monday, October 22, 2018 at 9:16:22 PM UTC+1, Patrick Smith wrote: > > On Fri, Oct 19, 2018 at 10:48 AM alanfo <alan...@gmail.com <javascript:>> > wrote: > >> In the light of all the feedback there's been, I've put together a >> proposal which sticks closely to the original design and only changes what >> most people consider needs to be changed in some way. Some recent ideas >> which seemed plausible but which I felt had little chance of adoption have >> been rejected. >> >> https://gist.github.com/alanfo/72f07362d687f625a958bde1808e0c87 >> > > I like your simplified syntax for contracts, but I would prefer to see > contracts specify one type at a time, rather than several. I think this > will be easier for people to understand when type parameters are > independent or have only one-way dependencies, and that this case will be > much more command than the case of mutual dependencies. A suitable syntax > might be something like > > contract Addable { > > // Note: using the contract name to represent the type being described > > Addable + Addable > > } > > func SliceSum[type T](s []T) T { > > var sum T > > for _, t := range s { > > sum = sum + t > > } > > } > > contract List[type T] { > > func (List) Len() int > > func (List) At(int) T > > } > > func ListSum[type L List[T], T Addable](l L) T { > > var sum T > > for n := 0; n < l.Len(); n++ { > > sum = sum + l.At(n) > > } > > } > > contract Comparable { > > func (Comparable) Equal(Comparable) bool > > } > > contract Hashable { > > Comparable // embedding > > func (Comparable) Hash() uint64 > > } > > // An associative array using user-defined notions of equality and hashing > type Map[type K Hashable, V] struct { ... } > > contract NodeType[type E] { > > func (NodeType) Edges() []E > > } > > contract EdgeType[type N] { > > func (EdgeType) Nodes() (N, N) > > } > > type Graph[type N NodeType[E], type E EdgeType[N]] struct { ... } > > This is somewhat like the "interfaces instead of contracts" proposals, but > without trying to force everything into interfaces. To enforce one type per > contract, we could have a rule that every line in a contract that is not an > embedding of another contract must explicitly use the contract name, and > the receiver type of a method must be either ContractName or *ContractName. > -- 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.