A new solution of type list in generic.

236 views
Skip to first unread message

redsto...@gmail.com

unread,
Dec 28, 2020, 6:29:44 AM12/28/20
to golang-nuts
If generic is inevitable, make it better.  The type list in the current draft is so special that  it is added only for operators. I think it will bring complexity and inconsistens in go. So I get an idea to replace it.

type bigger[T bigger] interface{
BiggerThan(T) bool
}

func max[T bigger[T]](a, b T) T{
if a.BiggerThan(b) {
return a
} else {
return b
}
}

type BiggerInt int

func (a BiggerInt) BiggerThan(b BiggerInt)bool{
return a > b
}

type BiggerFloat float32

func (a BiggerFloat) BiggerThan(b BiggerFloat)bool{
return a > b
}


max(1,2)

instead of operators we use  method. the generic call site remain the same.
If we allow the implicity type conversion between BiggerInt and int, this will work.

This solution will write more code when we define BiggerThan in each type. But we remove type list in interface. How do you think it?

burak serdar

unread,
Dec 28, 2020, 11:19:49 AM12/28/20
to redsto...@gmail.com, golang-nuts
On Mon, Dec 28, 2020 at 4:30 AM redsto...@gmail.com
<redsto...@gmail.com> wrote:
>
> If generic is inevitable, make it better. The type list in the current draft is so special that it is added only for operators. I think it will bring complexity and inconsistens in go. So I get an idea to replace it.

There have been similar proposals before. Interface-only contracts do
not work for primitive types, as you realized, so there were
suggestions to work around that limitation, as you already did.

I believe the question you should ask is that in a language with no
operator overloading, what is the purpose of defining a constraint
that allows operator >? That simply means numeric types and string. I
think it is much more concise and explicit to say "the function
expects a numeric or string" than to say "the function expects a type
on which > can be used".

>
> type bigger[T bigger] interface{
> BiggerThan(T) bool
> }
>
> func max[T bigger[T]](a, b T) T{
> if a.BiggerThan(b) {
> return a
> } else {
> return b
> }
> }
>
> type BiggerInt int
>
> func (a BiggerInt) BiggerThan(b BiggerInt)bool{
> return a > b
> }
>
> type BiggerFloat float32
>
> func (a BiggerFloat) BiggerThan(b BiggerFloat)bool{
> return a > b
> }
>
>
> max(1,2)
>
> instead of operators we use method. the generic call site remain the same.
> If we allow the implicity type conversion between BiggerInt and int, this will work.
>
> This solution will write more code when we define BiggerThan in each type. But we remove type list in interface. How do you think it?
>
> --
> 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...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/debe7749-fe96-4587-814b-a76ee7f48528n%40googlegroups.com.

Ian Lance Taylor

unread,
Dec 28, 2020, 12:35:37 PM12/28/20
to redsto...@gmail.com, golang-nuts
I think that one of the minimal requirements for any generics proposal
is the ability to write a Max function that works for variables (not
constants) of any integer or floating-point type. If we can't write
Max, then there are all sorts of useful functions that we can't write.
And since the predeclared types don't have methods, the approach you
describe doesn't permit us to write Max.

Ian

redsto...@gmail.com

unread,
Dec 28, 2020, 8:13:41 PM12/28/20
to golang-nuts
Constant here is just an example. We can use varaibles.
var a, b int
c := max(a,b)
on the base of type inference.
Predeclared types don't have methods.But we can extend the type restriction, using implicit type conversion here, between BiggerInt and int, BiggerFloat and float32.
I think the implicit type conversion here is better than type list in interface.

redsto...@gmail.com

unread,
Dec 28, 2020, 9:09:45 PM12/28/20
to golang-nuts
But interface-only contracts do work here, as I suggest, only need to introduce implicit type conversion.  Type list is not so good as you say. When defining the generic funcition max, I am not expecting number and string, and I am not expecting operator>,  I am expecting method BiggerThan. Using methods keeps consistency of the language, and it is much more clear than type list and operators. Type list is strange in the interface with methods, and causes a lot of other problems. This solution only adds complexity in generic libraries. But the type list invades in the language core.  So far as I can see, the implicit type conversion is better, at least it can be considered. If there is  technical difficulty on the implicit type conversion, we can discuss it.

burak serdar

unread,
Dec 28, 2020, 9:43:29 PM12/28/20
to redsto...@gmail.com, golang-nuts
On Mon, Dec 28, 2020 at 7:10 PM redsto...@gmail.com
<redsto...@gmail.com> wrote:
>
> But interface-only contracts do work here, as I suggest, only need to introduce implicit type conversion. Type list is not so good as you say. When defining the generic funcition max, I am not expecting number and string, and I am not expecting operator>, I am expecting method BiggerThan. Using methods keeps consistency of the language, and it is much more clear than type list and operators. Type list is strange in the interface with methods, and causes a lot of other problems. This solution only adds complexity in generic libraries. But the type list invades in the language core. So far as I can see, the implicit type conversion is better, at least it can be considered. If there is technical difficulty on the implicit type conversion, we can discuss it.

If all you need is a method BiggerThan, then what you need is an
interface, not generics.
> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/3aa54c64-b76e-4ccf-bbf2-b42c3c12d24fn%40googlegroups.com.

Ian Lance Taylor

unread,
Dec 29, 2020, 12:51:13 AM12/29/20
to redsto...@gmail.com, golang-nuts
On Mon, Dec 28, 2020 at 5:14 PM redsto...@gmail.com
<redsto...@gmail.com> wrote:
>
> Constant here is just an example. We can use varaibles.
> var a, b int
> c := max(a,b)
> on the base of type inference.
> Predeclared types don't have methods.But we can extend the type restriction, using implicit type conversion here, between BiggerInt and int, BiggerFloat and float32.
> I think the implicit type conversion here is better than type list in interface.

You are suggesting that we have implicit type conversion from one
defined type to another defined type, in order to add new methods?

What if we have something like

type MyInt int

func (i MyInt) String() string { return fmt.Sprint(i) }

func F(a, b MyInt) Myint {
return Max(a, b)
}

Is that going to implicitly convert from MyInt to BiggerInt? Will the
String method carry over?

In general I would be quite nervous about implicit type conversion.
It makes it very easy to get confused about what type you have and how
that type changes. That is why Go has very little implicit type
conversion.

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...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/bff7f05e-e406-49c3-9c5b-e8404cbc7c4en%40googlegroups.com.

redsto...@gmail.com

unread,
Dec 29, 2020, 10:24:22 PM12/29/20
to golang-nuts
You are right. The implicit type conversion will bring confusion. I give up. But I still think the type list is not a good idea. I'd rather not support operators than use type list.
Reply all
Reply to author
Forward
0 new messages