On Mon, Oct 22, 2018 at 1:53 PM Marvin Renich <m...@renich.org> wrote: > > * Burak Serdar <bser...@ieee.org> [181018 15:08]: > > tbh, I am not trying to avoid operator overloading, I am trying to > > avoid the contracts. With operator overloading, you can write: > > > > func F(a,b type T like(int,X)) { > > if a<b { > > ... > > } > > } > > > > provided X is a type that supports <. > > Are you trying to avoid the concept of contracts or the specific syntax > proposed in the design draft?
My intent was to use existing types as contracts instead of an abstract contract specification. In this scenario, a contract is a more abstract concept that an interface. Above, type T like(int,X) would mean: - func F compiles for T=int and T=X - F can be instantiated for any type derived from int or X So instead of specifying the precise type semantics required by F, you'd approximate the intent and declare that F would work for types that look like int, and X. When you apply the same idea to structs: type T like struct {a, b, int} would mean that T can be substituted by any struct containing two int fields called a and b. This idea ran into problems later on: I cannot explain simple contracts such as "type T must support ==". > > The more I read through this thread, the more convinced I am that > interfaces and contracts are, and should be, separate entities. While > the "implements" proposal is simple and rather elegant, it has a few > limitations that have been pointed out elsewhere. My objection to it is > that it conflates the concept of a common set of methods on a type and a > common set of attributes of a function type parameter. > > The current implementation of interfaces uses (exactly one layer of) > boxing of a non-interface type. > > The intended implementation of generics provides zero layers of boxing > around a non-interface or interface type. > > If you shoehorn generics into an extension of interfaces, you are > conflating two completely different implementation goals, and now we > cannot think of interfaces as a simple box. > > By using contracts (hopefully _not_ with the syntax proposed in the > design draft) and function type parameters, the programmer can clearly > distinguish from the code how the compiler is going to treat both > interface arguments and generic function type parameters. > > I contend that the "implements" design, while being slightly (and only > slightly) simpler syntactically, is a subset of my suggested declarative > contract syntax. > > It also has the disadvantage that every method that "implements" an > operator must explicitly declare it. Declarative contracts allow taking > an existing type written elsewhere that has a method with appropriate > signature and semantics, and using it with a newly created contract > without modifying the original type. This is analogous to a newly > created interface that is automatically implemented by a previously > defined type without modifying the type. > > For the type > > type MySortable struct { > name string > sortkey id > } > > Using implements: > > type Sortable interface { > implements < > } > > func (r MySortable) LessThan (s MySortable) bool implements < { > return r.sortkey < s.sortkey > } > > Using declarative contracts: > > contract Sortable(U) { > U: LessMethod(LessThan) > } > > func (r MySortable) LessThan (s MySortable) bool { > return r.sortkey < s.sortkey > } > > Actually, I think I would define it like this: > > contract Sortable(U) { > U: Operator(<, LessThan) > } > > Note that my earlier message was not a full blown proposal, just a > suggested syntax without any attempt to specify semantics of specific > contract keywords. > > Because contract keywords are in their own namespace and do not conflict > in any way with any language keywords or user identifiers, extending the > attributes that can be declared by a contract can be done at any time > without any backwards incompatibility. The list of contract keywords > can initially be very short and sweet, and can then be extended as > desired features are identified. > > So, interfaces are to method sets on a type as contracts are to the type > parameters on a generic function or type. Don't try to shoehorn > generics into interfaces. > > The contract paradigm allows specifying interaction of multiple types in > a way that implements does not. Also, it specifies in a single place a > set of attributes that can be used in multiple functions and types > spread out over multiple packages in the same way that interfaces allow > defining in one package a set of methods that can be used to describe > variables in multiple packages. > > One package can define a contract, that contract can be used in multiple > packages to define type-parametric functions and types, and then any > type defined elsewhere that satisfies the contract can be used with the > aforementioned functions and types. > > Finally, using a named contract can give meaning to a set of type > parameter attributes in the same way that we can now define "type Widget > int" and "type Color int" and refer to them in code to express the > intended use of the int. The implements proposal lacks this ability to > identify the programmer's intent. > > ...Marvin > > -- > 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. -- 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.