Just going through how xingtao zhao's examples would look under my own 
proposal:

The first one would be:

    contract Foo(T) {
        union{ int, float64, complex128 }(T)
        interfaceA(T)
    }

Note though that this could only be satisfied by defined types based on 
int, float64 or complex128 as those types don't have methods themselves and 
so couldn't satisfy interfaceA. 


The second one would be approached in a different way which doesn't require 
the slice element type to be deduced or a contract to be written:

    func slicer(type T Foo)(s []T, ...) ... {
        // do something with s
    }

or even non-generically:

    func slicer2(s []Foo, ...) ... { ... }


The third one would also be approached in a different way but still 
requires a contract:

    contract Map(K, V) {
        Comparable(K)
        Foo(V)
    }
     
    func mapper(type K, V Map)(m map[K]V, ...) ... {
        // do something with m
    }

Finally, a struct type with a field f (say of type int) could be expressed 
like this:

    contract Struct(T) {
        struct{ f int }(T)
    }

Alan

On Tuesday, September 18, 2018 at 5:51:03 PM UTC+1, xingtao zhao wrote:
>
> I have the similar thought as the thread. In terms of a contract, it is 
> mainly to express these:
>
>    1. Methods set: this could be easily expressed by interface
>    2. Operators set: In go, we could not add or remove the existing 
>    operator set for a given type, which is completely inherited from its 
>    underlying type. So it is equivalent to explicitly express operation set 
> vs 
>    to express the union of underlying types.
>    3. Type conversion:
>       1. conversion between types with the same underlying type
>       2. conversion between numeric types
>       3. conversion from concrete types to interface
>    
> So it is obviously that what we are lacking is: expressing underlying 
> types and expressing the combination of them, i.e. union type. So maybe a 
> contract could be written like this:
>
> contract Foo(T) {
>   int(T) || float64(T) || complex128(T)  // underlying type: int, float64, 
> complex128
>   InterfaceA(T)                                    // at the same time, it 
> should satisfy InterfaceA
> }
>
> contract Slice(S) {
>   []T(S) && Foo(T)    // S is a slice, and retrieve the element type to T, 
> and T should match contract Foo
> }
>
> contract Map(M) {
>   (map[K]V)(M) && Foo(V)  // M is a map, whose value type match contract 
> Foo.
> }
>
> There is still no way to express that a type should have a field "f" - But 
> maybe we can accept this?
>
> In this case, contract is more orthogonal to the existing concepts in go - 
> we already have the way to express the method set of a type (interface), it 
> is no needed to be able to express it in contract again. 
>
>
> On Monday, September 17, 2018 at 4:54:04 PM UTC-7, alanfo wrote:
>
>> Thanks for your comment, Patrick.
>>
>> Although I've relied on compiler magic for my previous proposals, I 
>> believe we should keep it to a minimum if we can, The 'union' and 'except' 
>> idea would allow us to compose any group of types we want from the basic 
>> built-ins and, even within the standard library, it would always be clear 
>> from looking at the underlying code exactly what those groups comprised. 
>>
>> For me that would be a valuable feature and would still be significantly 
>> less complex than the draft generics design where every operator used has 
>> to be spelled out. Under this proposal, the allowable operators/conversions 
>> etc. are implicit from the types used.
>>
>> Alan
>>
>> On Monday, September 17, 2018 at 8:16:38 PM UTC+1, Patrick Smith wrote:
>>>
>>> I think your idea of creating standard contracts to represent similar 
>>> types is a good one. However, you don't have to say how those contracts are 
>>> written, just what they do. No need for typecheck, union, except, etc. For 
>>> example,
>>>
>>> Integer(T) - T is an integer type
>>> Float(T) - T is a floating point type
>>> Complex(T) - T is a complex type
>>>
>>> For contracts in the standard library, we can just invoke "compiler 
>>> magic" to explain how they work. Trying to explain the mechanism merely 
>>> adds complexity.
>>>
>>

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