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.