On Fri, Aug 2, 2019 at 6:55 PM 'Axel Wagner' via golang-nuts <
golang-nuts@googlegroups.com> wrote:

>
> contract Comparable(T) {
>   T comparable, Equal(T) bool
> }
>

Wait, does this work? I mean, `comparable` is a contract, but it's being
used as a constraint. Could you also write:

contract Equaler(T) {
    T Equal(T) bool
}

>
contract Comparable(T) {
    T comparable, Equaler
}

? Or is comparable just special? Or does this not actually work, even for
comparable? This would certainly be convenient if you could do it, though
it means contracts involving a single type are privileged over others (you
can create a disjunction between constraints, but not between contracts,
for example). It seems like if you can create contract constraints like
this, you'd also want to be able to make *generic* contract constraints, to
capture things like

contract Appender(type Elem)(T) {
    T Append(...Elem) T
}

contract Appendable(type Elem)(T) {
    T []Elem, (Appender(Elem)) // Parens to avoid parsing like a method
constraint
}

The same issue comes up with the

    switch T.(type) { ... }

idea. Even if you're only constraining one type at a time like this, you
might still need to express a relationship to another type parameter.
Unless this is allowed:

    switch (type) {
        case comparable(T): ...
        case Equaler(T): ...
    }

On Fri, Aug 2, 2019 at 6:55 PM 'Axel Wagner' via golang-nuts <
golang-nuts@googlegroups.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
>> <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
> <https://groups.google.com/d/msgid/golang-nuts/CAEkBMfELVwJEkyLUJUsKGjUzqBVofDNRtkjta7%2BVXEFN_ZGtUg%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/CANjmGJvKgk5bFr7NM2m0EihQfb1XEXtYCdayNf-VHNUONV1UJw%40mail.gmail.com.

Reply via email to