Re: [go-nuts] [generics]: Pointer methods in interfaces used as constraints?

2020-08-15 Thread Ian Lance Taylor
On Fri, Aug 14, 2020 at 9:31 PM Patrick Smith  wrote:
>
> https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md#pointer-method-example
>  has this example:
>
> // Setter2 is a type constraint that requires that the type
> // implement a Set method that sets the value from a string,
> // and also requires that the type be a pointer to its type parameter.
> type Setter2(type B) interface {
>
> Set(string)
>
> type *B
>
> }
> // FromStrings2 takes a slice of strings and returns a slice of T,
> // calling the Set method to set each returned value.
> //
> // We use two different type parameters so that we can return
> // a slice of type T but call methods on *T aka PT.
> // The Setter2 constraint ensures that PT is a pointer to T.
> func FromStrings2(type T interface{}, PT Setter2(T))(s []string) []T {
>
> result := make([]T, len(s))
>
> for i, v := range s {
>
> // The type of &result[i] is *T which is in the type list
>
> // of Setter2, so we can convert it to PT.
>
> p := PT(&result[i])
>
> // PT has a Set method.
>
> p.Set(v)
>
> }
>
> return result
>
> }
>
>
> I wonder if it might be worthwhile to allow specifying pointer methods in 
> interfaces, so that we could write instead
>
> type Setter3 interface {
>
> // For type T to implement Setter3, *T must have a Set method.
>
> * Set(string)
>
> }
>
> func FromStrings3(type T Setter3(T))(s []string) []T {
>
> result := make([]T, len(s))
>
> for i, v := range s {
>
> result[i].Set(v)
>
> }
>
> }
>
>
> This is simpler in two ways: FromStrings3 only needs one interface 
> constraint, and it does not need to convert &result[i] to a type parameter, 
> but can call result[i].Set(v) directly.
>
> I imagine interfaces containing pointer methods should be used only as 
> constraints on type parameters, not as normal interfaces.
>
> I have no idea if such cases arise often enough to make this idea worthwhile.

This suggestion is a little bit like the pointer methods we had in an
earlier version of the design draft
(https://go.googlesource.com/proposal/+/572fea69936c3f25a99860fce22aeb23a3263ca3/design/go2draft-type-parameters.md#pointer-methods).

I'm not sure how that would work if such an interface type were used
other than as a type constraint (of course we could forbid that case).
An interface currently holds either a pointer or a value.  If the
interface says that the method must be on the pointer type, then
presumably the interface will hold a value.  But then what address do
we take to call the method?  Taking the address of the value stored
inside the interface would mean that an interface was a reference type
rather than a value type.  I think that would be a subtle distinction
that might increase confusion when using the language.  Though
admittedly the points in this area are already rather subtle (e.g.,
the FAQ answer https://golang.org/doc/faq#pointer_to_interface).

That side, at the moment I think that the constraint type inference
idea is more versatile, as it works for types other than pointers.

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/CAOyqgcWxTFPM_fmL%3DyE9VNgob1_UZYufyz94F%3D5rov1YcJU72Q%40mail.gmail.com.


[go-nuts] [generics]: Pointer methods in interfaces used as constraints?

2020-08-14 Thread Patrick Smith
https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md#pointer-method-example
has this example:

// Setter2 is a type constraint that requires that the type
// implement a Set method that sets the value from a string,
// and also requires that the type be a pointer to its type parameter.
type Setter2(type B) interface {

Set(string)

type *B

}
// FromStrings2 takes a slice of strings and returns a slice of T,
// calling the Set method to set each returned value.
//
// We use two different type parameters so that we can return
// a slice of type T but call methods on *T aka PT.
// The Setter2 constraint ensures that PT is a pointer to T.
func FromStrings2(type T interface{}, PT Setter2(T))(s []string) []T {

result := make([]T, len(s))

for i, v := range s {

// The type of &result[i] is *T which is in the type list

// of Setter2, so we can convert it to PT.

p := PT(&result[i])

// PT has a Set method.

p.Set(v)

}

return result

}


I wonder if it might be worthwhile to allow specifying pointer methods in
interfaces, so that we could write instead

type Setter3 interface {

// For type T to implement Setter3, *T must have a Set method.

* Set(string)

}

func FromStrings3(type T Setter3(T))(s []string) []T {

result := make([]T, len(s))

for i, v := range s {

result[i].Set(v)

}

}


This is simpler in two ways: FromStrings3 only needs one interface
constraint, and it does not need to convert &result[i] to a type parameter,
but can call result[i].Set(v) directly.

I imagine interfaces containing pointer methods should be used only as
constraints on type parameters, not as normal interfaces.

I have no idea if such cases arise often enough to make this idea
worthwhile.

-- 
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/CAADvV_ut8xmDyaOonOOKt0pUr3UxYEqBvpV%2Bh8K5HNsHbwMwQA%40mail.gmail.com.