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
> <https://groups.google.com/d/msgid/golang-nuts/CAEd86Tz4tvx3qPZ4fV86AyV-B8YOXEMZMR-L4f6fcTyAuX_eXQ%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>

-- 
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/CAEkBMfELVwJEkyLUJUsKGjUzqBVofDNRtkjta7%2BVXEFN_ZGtUg%40mail.gmail.com.

Reply via email to