Hi,

Some comments in-line:

> > Who does this proposal help, and why?
> go programmers who want to reduce boiler plate code.

I believe you should definitely be more explicit with the problem you are
trying to solve. "Today, if you want to do X, you have to write Y. That is
bad, because Z".

There are many different kinds of boiler plate, so just saying you help "Go
programmers who want to reduce boiler plate" carries little to no
information.

> interfaces and named aliases would become allowable receivers. The change
would just be syntactic sugar for functions that accept this interface.

I don't have a specific reference handy, but more or less exactly this has
been proposed a couple of times in the past and always been rejected.
So, apologies for being harsh, but I would predict that this has an
essentially zero chance of being accepted.

I also think one thing we should be clear on, is that methods fundamentally
are never "just syntactic sugar for functions" - unless you really are
proposing Uniform Function Call Syntax. In particular, your proposal has
name spacing implications - it would be possible to have two methods of the
same name on different interface types, while it is not possible to have
two *functions* of the same name, even if they accept different interfaces
as their first argument.

So, this is not just syntactic sugar, it carries semantic meaning. And if
it where, it would not be likely to solve the problem you are trying to
solve.

> There are some restrictions:
>
> R1: Just like normal methods, “interface methods” can only be defined
within the package the interface is defined. This prevents imported code
from > potentially breaking or overriding the intended functionality.

I don't think this is a good idea. Interfaces, by their nature, are mostly
package-agnostic. That is, I can define an interface
type MyReader interface{ Read(p []byte) (int, error)
and while it is not *identical* to io.Reader, it is mostly equivalent, that
is, they are mutually assignable.

I believe it would be confusing for methods on a `MyReader` to disappear,
when assigning them to an `io.Reader` and to appear, when assigning an
`io.Reader` to a `MyReader`.

Note also, that Go has interface type-assertions. So how would this work,
for example?

func (r MyReader) WriteTo(w io.Writer) (int64, error) { … }
type R struct{}
func (R) Read(p []byte) (int, error) { return len(p), nil } // implements
io.Reader
func main() {
    _, ok := io.Reader(R{}).(io.WriterTo) // fails
    mr := MyReader(R{})
    _, ok = io.Reader(mr).(io.WriterTo) // succeeds, presumably?
    ch := make(chan io.Reader, 1)
    ch <- mr
    (<-ch).(io.WriterTo) // fails? succeds?
}

That is, a `MyReader` would implement `io.WriterTo`. But if it is
intermediately stored in an `io.Reader` (say, by passing it through a
channel), the compiler no longer knows if and where to find a `WriterTo`
method.

This really is just a corollary/demonstration of why it's confusing for
methods to appear/disappear when converting them between io.Reader and
MyReader.

> R2: interface methods cannot override existing methods. Attempting to
cast an object to an interface that it already fulfills or partially
fulfills would be
> a compile time error. This prevents interfaces from becoming
self-fulfilling, or overriding expected functionality. The compile time
error is necessary
> so future updates to packages don’t change functionality unexpectedly.

How do you deal with a situation where the *dynamic type* of an interface
has that method, but not its static type? That is, what if I assign an
`*os.File` to a `MyReader`, for example? What if I assign an `*os.File` to
an `io.Reader` and then convert that to a `MyReader`?

> My motivation for this feature is to mitigate limitations on dynamic
types. Consider the typical approach to handling dynamic json.
> […]
> Access could be simpler through a hypothetical jnode package.
> […]

I believe you can functionally achieve the same result if you make `node` a
struct type with an `UnmarshalJSON` method and an `any` or `map[string]any`
field or something like that.

> Fortunately, there’s no need to rush into this. We could start by saying
extension methods do not contribute to the method set, and therefore do not
> help fulfill interfaces. Unfortunately, that caveat would fall to
programmers to understand, raising the bar for learning go. I believe the
ultimate
> design here would definitely be to allow the extension methods into the
type’s method set.

Note that the resulting confusion of having methods that are not in the
method set, when considering interface satisfaction, is why we do not have
extra type parameters on methods <https://github.com/golang/go/issues/49085>.
I don't believe this proposal has significantly more advantages than
allowing that would have (it probably has significantly fewer) so I don't
think this proposal would overcome that concern.

> This example illustrates how the code rewriting can lead to a kind of
support for generic methods.
>
> Theoretically, this could be a starting point for how generic methods
might be possible, though there’s a lot of investigation to happen
> before that’s possible.

I think it rather demonstrates why it runs into the same fundamental issues
that the proposal to support extra type parameters on methods has.
It seems likely to me, that if we could overcome those issues, we'd prefer
to support extra type parameters on methods, instead of this proposal.

> > Is this change backward compatible?
> Because defining methods on interface receivers has been illegal, I
believe this is a backward compatible change.
> No existing code will be doing this.

That depends on a couple of details - specifically questions the kinds of
questions I asked above. Depending on how you answer those, the fact that
the dynamic method set of a type can change by passing them through
interface types could break compatibility.

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

Reply via email to