Sorry, I was thinking that Foo was an interface (rather than an existing 
contract), so the second example couldn't be written non-generically.

In the third example you could also merge the two contracts into one:

     contract MapFoo(K, V) {
          Comparable(K)
          union{ int, float64, complex128 }(V)
          interfaceA(V)
     }

     func mapper(type K, V MapFoo)(m map[K]V, ...) ... {
         // do something with m
     }

Alan

On Tuesday, September 18, 2018 at 7:42:06 PM UTC+1, alan...@gmail.com wrote:
>
> 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