Clear as mud. 

> On Aug 2, 2019, at 6:03 PM, 'Axel Wagner' via golang-nuts 
> <golang-nuts@googlegroups.com> wrote:
> 
> Just tried running it through the prototype type-checker and one correction: 
> You also have to convert `a` and `&a` to interface{}, so that you are allowed 
> to type-assert on them:
>   if e, ok := (interface{}(a)).(equaler(T)); ok { return e.Eq(b) } 
>   if e, ok := (interface{}(&a)).(equaler(T)); ok { return e.Eq(b) }
> 
> Anyway, I hope by now the extreme hackishness of this "solution" is clear :)
> 
>> On Sat, Aug 3, 2019 at 12:55 AM Axel Wagner <axel.wagner...@googlemail.com> 
>> wrote:
>> FWIW:
>> interface{}(a) == interface{}(b)
>> would work. It would panic if a and b have the same, non-comparable type. 
>> But if you know the type is equal and comparable, it's well-defined and does 
>> what you want. So you have to modify your code a bit:
>> 
>> type equaler(type T) interface {
>>   Equal(T) bool
>> }
>> 
>> contract Comparable(T) {
>>   T comparable, Equal(T) bool
>> }
>> 
>> func Compare(type T Comparable)(a, b T) bool {
>>   if eq, ok := a.(equaler(T)); ok {
>>     return eq.Equal(b)
>>   }
>>   // Okay, this is weird, but: If you have `func (*T) Equal(T) bool`, a T 
>> (value) would
>>   // be accepted by the contract, as contracts don't distinguish between 
>> value and
>>   // pointer-receivers. But it would fail above type-assertion, as values 
>> don't include
>>   // pointer-methods in their method set.
>>   if eq, ok := (&a).(equaler(T)); ok {
>>     return eq.Equal(b)
>>   }
>>   return interface{}(a) == interface{}(b)
>> }
>> 
>> I can't think of anything in the current design draft preventing this from 
>> working (though I'm sure Ian can correct me if I'm wrong).
>> 
>> It's a special case for equality-comparison though, it doesn't generalize to 
>> any other operators.
>> 
>>> On Fri, Aug 2, 2019 at 10:40 PM Bruno Albuquerque <b...@gmail.com> wrote:
>>> Ok, it makes sense. I do think that supporting something like this might 
>>> make the proposal even more appealing as it will bring custom types 
>>> somewhat closer to builtin types by allowing generic functions/methods that 
>>> can act on both at the same time.
>>> 
>>>> On Fri, Aug 2, 2019 at 1:28 PM Ian Lance Taylor <i...@golang.org> wrote:
>>>> On Fri, Aug 2, 2019 at 1:12 PM Bruno Albuquerque <b...@gmail.com> wrote:
>>>> >
>>>> > I was thinking about a way to  "extend" usual operations (say, equality 
>>>> > checks) to types that can not be compared the usual way (they are not 
>>>> > "comparable" in the contract sense) and came up with something like this:
>>>> >
>>>> > // Just to use for type assertion later.
>>>> > type Equaler interface {
>>>> >   Equal(Equaler) bool
>>>> > }
>>>> >
>>>> > contract Comparable(T) {
>>>> >   T comparable(T), Equal(T) bool
>>>> > }
>>>> >
>>>> > func Compare(type T Comparable)(a, b T) bool {
>>>> >   if eq, ok := a.(Equaler); ok {
>>>> >     return eq.Equal(b)
>>>> >   }
>>>> >
>>>> >   return a == b  // Does this work at all?
>>>> > }
>>>> >
>>>> > Would this work? More specifically it looks to me that that if the 
>>>> > specific type is not comparable (But has the Equal method), the compiler 
>>>> > might see the "==" comparison in the function and give an error.
>>>> >
>>>> > One way around this would possibly be to use something similar to type 
>>>> > assertion (in this case, a and b would have to be asserted to 
>>>> > "comparable" which I guess is not possible as it is a contract). Or, the 
>>>> > compiler could be smart enough to know that if we reached that check, 
>>>> > then the type must be comparable (so it would also not give an error).
>>>> 
>>>> In the current design draft, that would not work.  The == operator is
>>>> not supported by all possible types, so it is not permitted.
>>>> 
>>>> We definitely don't want to rely on the compiler being smart enough.
>>>> Any such approach would require writing down the exact inference rules
>>>> that the compiler is permitted to use.  Otherwise different compilers
>>>> would behave differently.
>>>> 
>>>> One possibility we've toyed with is
>>>> 
>>>>     switch T.(type) { // Note: switch on type parameter itself, not a
>>>> value of that type.
>>>>     case Equaler:
>>>>         ...
>>>>     case comparable:
>>>>         // Permit using == operator here on values of type T in this case 
>>>> only.
>>>>     }
>>>> 
>>>> We'll see whether some such facility seems useful.  This is something
>>>> we can add later, if the current design draft seems workable.
>>>> 
>>>> Ian
>>> 
>>> -- 
>>> 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.
>>> To view this discussion on the web visit 
>>> https://groups.google.com/d/msgid/golang-nuts/CAEd86Tz4tvx3qPZ4fV86AyV-B8YOXEMZMR-L4f6fcTyAuX_eXQ%40mail.gmail.com.
> 
> -- 
> 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/CAEkBMfG2meXfm%2Bh1YF2iMTotYsaNq-yjVBB_v9pr9-v3BbDeVA%40mail.gmail.com.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/5A101184-948E-4096-B6BA-703B44E801E6%40ix.netcom.com.

Reply via email to