[generics] Simplification: Methods refer to original type parameters instead of re-specifying each time

116 views
Skip to first unread message

Randall O'Reilly

unread,
Jun 17, 2020, 6:45:35 AM6/17/20
to golang-nuts
You could save a fair amount of typing and eyestrain by not replicating the type params for types, in their methods:

type Vector(type T) []T

func (v *Vector) Push(x v.T) { *v = append(*v, x) }

////////////

type Map(type K, V) struct {
root *node(K, V)
compare func(K, K) int
}

func (m *Map) InOrder() *Iterator(m.K, m.V) {
type kv = keyValue(m.K, m.V) // convenient shorthand
sender, receiver := chans.Ranger(kv)()
var f func(*node(m.K, m.V)) bool
...
}

Could also just have the bare type param name without the field-like specifier (e.g., K, V instead of m.K, m.V) but that makes it less obvious what K and V are -- m.K makes it clear that K is something I can find if I look at the definition of the type of m.

This also enforces consistent naming of type parameters across all methods.

- Randy

Tyler Compton

unread,
Jun 17, 2020, 2:04:26 PM6/17/20
to Randall O'Reilly, golang-nuts
I think this syntax could get confusing when embedded fields is added to the mix:

type MyStruct(type T) struct {
    T
}

func (ms *MyStruct) MyMethod(t ms.T) {
    ms.T =  t
}

In this example. ms.T means two very different things depending on where they are used.

--
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/2605713E-73F3-4332-911D-D41EAE4DAF6A%40gmail.com.

Randall O'Reilly

unread,
Jun 17, 2020, 8:18:25 PM6/17/20
to Tyler Compton, golang-nuts
Good point!

I can think of 2 possible (non-mutex) solutions:

* Use an explicit type expression to refer to the type: `type(ms.T)` and the field is just `ms.T`

* Within the method scope, make `T` a valid type name, so you can just use `T` directly -- this might even be preferable overall as it is simpler, and should be clear what you're referring to in that context. May still need `ms.T` and `type(ms.T)` variants to refer to the type parameters outside of the method scope (being able to do so might make some type linkages across interface types simpler -- haven't worked that through at all..)

- Randy

Ian Lance Taylor

unread,
Jun 17, 2020, 8:39:26 PM6/17/20
to Randall O'Reilly, Tyler Compton, golang-nuts
On Wed, Jun 17, 2020 at 5:18 PM Randall O'Reilly <rcore...@gmail.com> wrote:
>
> Good point!
>
> I can think of 2 possible (non-mutex) solutions:
>
> * Use an explicit type expression to refer to the type: `type(ms.T)` and the field is just `ms.T`
>
> * Within the method scope, make `T` a valid type name, so you can just use `T` directly -- this might even be preferable overall as it is simpler, and should be clear what you're referring to in that context. May still need `ms.T` and `type(ms.T)` variants to refer to the type parameters outside of the method scope (being able to do so might make some type linkages across interface types simpler -- haven't worked that through at all..)

An earlier version of the design let people refer to type parameters
of the type without requiring them to be declared with the receiver.
But that meant that an identifier in a method was looked up first in
the method, then in the type parameters of the receiver, then in the
package. People found that additional scope rather confusing. It
wasn't completely obvious what would happen if the same name appears
as a package scope variable and as a receiver's type parameter.

Using ms.T avoids that problem but as observed it leads to a different
ambiguity. If we were to use that approach I think we would have to
forbid using the same name for a type parameter, a field, and a
method. But that would in turn make it hard to embed a type
parameter.

Ian
> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/3CC5CE67-BE33-40B4-9C84-371ADD69D729%40gmail.com.
Reply all
Reply to author
Forward
0 new messages