On Mon, Jul 29, 2019 at 2:25 PM, Ian Lance Taylor <i...@golang.org> wrote:

> The motivation is to avoid requiring contracts to specify whether a method
> is a pointer method or a value method, just as we do not require interface
> types to specify whether a method is a pointer method or a value method.
>

I'm not sure whether pointer method vs. value method is the distinction
that needs to be made. For the general purpose of writing code that calls
methods on arbitrary types, what we want to know is whether a
type-parameterized function should assume it needs an addressable value or
if it can use a non-addressable value of the parameter type to call a
method. Any references/dereferences that need to be done can be done
automatically as long as you know whether the value needs to be addressable
and the code is written accordingly (i.e. without needing to take the
address of an implicit variable). That might end up being represented in
the language as though you're passing pointers into the methods, but I
don't think that needs to map to whether the concrete method itself accepts
a pointer or a value.

To illustrate, if you have

    func Foo(type T ...)(slice []T) {
         for i := range slice {
             slice[i].DoStuff()
         }
    }

what sort of bound do you need on `T` so that it can handle each
combination of:

1. `T` is passed a value type `Arg` or a pointer type `*Arg`, and
2. `DoStuff` is defined on `Arg` or on `*Arg`?

Why you sort of want is a constraint like

    HasDoStuff(T), HasDoStuff(*T)

where at least one or the other should capture the `DoStuff` method in each
case, and thus the combined constraint should allow you to call methods
on/involving addressable `T` values (potentially based on the fiction that
the accepted type is `*T`). I'm not sure what the best way of write such a
constraint is, though, or how common this kind of case is.

On Mon, Jul 29, 2019 at 2:25 PM, Ian Lance Taylor <i...@golang.org> wrote:

> On Mon, Jul 29, 2019 at 7:05 AM Ilia Choly <ilia.ch...@gmail.com> wrote:
> >
> > When converting a non-pointer value to an interface, pointer methods
> cannot be used to satisfy the interface. Even though the compiler could add
> instructions to take the value's address, this is not allowed because it's
> error prone. Since pointer methods usually mutate the receiver, you don't
> want to be operating on a copy. https://play.golang.org/p/XDiki8_uHMs
> >
> > When reading the contracts proposal, I'm confused by the seemingly
> contradictory decision to allow pointer methods.
> https://go.googlesource.com/proposal/+/master/design/go2draft-contracts.md#methods
> >
> >> In order to avoid worrying about the distinction between value methods
> and pointer methods, in a generic function body all method calls will be
> pointer method calls. If necessary, the function body will insert temporary
> variables, not seen by the user, in order to get an addressable variable to
> use to call the method ...This makes it easier to understand which types
> satisfy a contract, and how a contract may be used. It has the drawback
> that in some cases a pointer method that modifies the value to which the
> receiver points may be called on a temporary variable that is discarded
> after the method completes. It may be possible to add a vet warning for a
> case where a generic function uses a temporary variable for a method call
> and the function is instantiated with a type that has only a pointer
> method, not a value method.
> >
> >
> > The same example converted to use interfaces fails
> https://play.golang.org/p/FBbXQw7dKL6 What's the motivation for this
> design decision?
>
> The motivation is to avoid requiring contracts to specify whether a
> method is a pointer method or a value method, just as we do not
> require interface types to specify whether a method is a pointer
> method or a value method.  It does make it possible to write certain
> kinds of bugs, but it's not clear how much that arises in practice.
>
> That said, it's likely that we will have to modify contracts to
> require a pointer method in some cases, in order to separate defining
> a variable of some type with invoking pointer methods on that
> variable, so I would not be surprised if this aspect of the design
> draft is changed.
>
> 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/CAOyqgcWgzkqS4GHH%2BbcQd6KNGJrRd1v2d0D2GU5LsomJF0SL%3Dw%40mail.gmail.com
> .
>

-- 
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/CANjmGJsJrE4oWiJvU-FJgmE7sjoFDn1d8u3e7mirmjo%3DZwd02A%40mail.gmail.com.

Reply via email to