* 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?

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.

Reply via email to