> Yes, I think that the ability to write generics using operators is not
> optional.  As I've said before, there are some functions that must be
> possible to write using any plausible generics mechanism.  One of them
> is the Min function that returns the smaller of two values of some
> ordered type.  If we can't write that trivial function, our generics
> mechanism is not usable for practical code.

I don't think that's quite true. You can write it, it's just not as
nice to use with builtin types:

func Min[type T Lesser](a, b T) T {
    if a.Less(b) {
        return a
    }
    return b
}

To use it with (for example) int, you need to write a wrapper type, for example:

type Int int
func (i Int) Less(j Int) bool { return i < j }

And then call it like so:

Min(Int(2), Int(3))

It's not pretty, but it definitely works
(https://go2goplay.golang.org/p/i6Q3tF-QwgH). This was kind of the
situation with sort.Sort (until sort.Slice came along), so it doesn't
seem any worse than that. Or you could instead define a generic type
"Ord" instead of Int:

type Ord[type T Ordered] T
func (i Ord[T]) Less(j Ord[T]) bool { return i < j }

And use it like so:

Min(Ord[int](2), Ord[int](3))

Or if type inference were improved to handle that case:

Min(Ord(2), Ord(3))

It's not pretty, partly because you get an Int/Ord result instead of a
plain int, but not terrible either.

So it seems to me it's not a case of "we can't write that trivial
function" -- it just requires a bit of type conversion. So either way
-- with your approach or this approach -- it's klunky for one of the
cases:

1) Assuming type lists and a function which takes a comparator func
like "func Min[type T](a, b T, less func(x, y T) bool) T" -- in this
case you have the klunkiness of having to import (or define)
"primitives" and specify the comparison func even when it's obvious:
Min(2, 4, primitives.Less)
2) With no type lists and a function which takes a "lesser" like "func
Min[type T Lesser](a, b T) T" -- in this case you have the klunkiness
of having to use wrapper types, like we did with sort.Sort back in the
day.

> Defining operators for every operation that applies to a builtin type
> in Go is surprisingly hard.  I think we wind up needing something like
> 40 different methods.  That is not a simple approach.

Perhaps, but presumably a lot of them wouldn't be common, and we could
start with just 2 or 3 or 4. It seems like "comparable" is essential
(even in the current design with type lists), but even just adding
"lesser" or similar on top of that would go a long way: sorting,
sorted containers, min, etc. Then again, I guess as soon as you let
one or two in, people will clamour for them all...

> package methods
> type lesser(type T) interface { Less(T) bool }
> func Less(type T lesser)(a, b T) bool { return a.Less(b) }
>
> and now you pass methods.Less to the function in question.

That's a neat trick.

-Ben

-- 
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/CAL9jXCFVJmEQ%3DZ9JdfawL06Zy1YvNHdci4mTO55CrSr4zhzkLw%40mail.gmail.com.

Reply via email to