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.