support new method on non-local types

741 views
Skip to first unread message

sleepy

unread,
Sep 14, 2014, 3:29:49 AM9/14/14
to golan...@googlegroups.com
why not Go support new method on non-local types, I found this is very useful when I'm using the html (code.google.com/p/go.net/html) library.
type html.Node has several properties like: Parent, NextChild, NextSibling,.... whose type are also html.Node
but the html library offers too little functionality and I need to extend it to add more functions to html.Node

of cause, I can add the functions by define a new type, like:
      type MyNode html.Node
or
      type MyNode struct {
           html.Node
      }

but this does not works well, asI have to do a lot of type conversions for the properties (Parent, NextChild....)

I don't think this is hard to do in Go, and C# already support this, by define the so called "Extension Method".

Ian Lance Taylor

unread,
Sep 14, 2014, 1:26:57 PM9/14/14
to sleepy, golang-nuts
On Sun, Sep 14, 2014 at 12:29 AM, sleepy <zhang...@gmail.com> wrote:
>
> why not Go support new method on non-local types,

Because it makes it ambiguous whether a type satisfies an interface or
not, depending on where a value of that type was created.

Ian

sleepy

unread,
Sep 15, 2014, 10:22:54 PM9/15/14
to golan...@googlegroups.com, zhang...@gmail.com
we do not care about the actual object when using an interface, so why it depend on where the object was created?

and if this is the case, how about ignore the 'extension method' when converting object to interface? this is what Microsoft done for C# (also because interface must be explicit declared in c#).

Bomin

Jesse McNelis

unread,
Sep 15, 2014, 10:41:15 PM9/15/14
to sleepy, golang-nuts
On Tue, Sep 16, 2014 at 12:22 PM, sleepy <zhang...@gmail.com> wrote:
> we do not care about the actual object when using an interface, so why it
> depend on where the object was created?
>
> and if this is the case, how about ignore the 'extension method' when
> converting object to interface? this is what Microsoft done for C# (also
> because interface must be explicit declared in c#).

In Go the primary purpose of methods is to implement interfaces.
A method that can't be used to implement an interface should probably
be just a function.

atomly

unread,
Sep 16, 2014, 3:09:38 AM9/16/14
to sleepy, golang-nuts

While I agree that this sort of functionality is incredibly, incredibly useful-- I'm primarily a Scala dev for my day job these days and this is one of the more popular and powerful features, though they have given it the unfortunate name of "pimping"-- it is one of the major pain points, especially for new people to the language, and can get convoluted and difficult to reason about rather quickly. Scala does it with something it calls implicit conversions. Basically you define a new subtype of the object in question and add the desired functionality there, then define an implicit method to convert the existing type to your new type. So, if I defined something like a RichNode with a prettyPrint method on it and implicit conversions from all those types you listed to this new RichNode, I could just call .prettyPrint() as if it existed on the original and the compiler would use implicit resolution to do the conversion for me.

I don't see how something like this could work at all in Go's type system, though, since a type is essentially only defined by what methods it contains and there is no notion of subtyping. Perhaps you could make a NodeMangler that is a utility class, essentially a correction of functions that operate on a Node and has all the functionality you want? Then, anywhere you need to in the code, you just call any of those methods, passing along any of these different kinds of Node?

atomly

--
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.
For more options, visit https://groups.google.com/d/optout.

Eugene OZ

unread,
Sep 16, 2014, 4:08:03 AM9/16/14
to golan...@googlegroups.com
If object has all methods to implement interface and all signatures of methods are correct, "we" should not do any additional checks. If my opionion is wrong - please let me know, why.

Tahir

unread,
Sep 16, 2014, 4:14:32 AM9/16/14
to golan...@googlegroups.com, zhang...@gmail.com
I can imagine that this because interfaces are satisfied implicitly. Extension of an API you don't own is a bit smelly to me (1. you can't share code, 2. if the API owner evolves it, it might conflict with your own extensions). 
But if I understand, you would like something that would be akin to having a main vtable and a secondary one for extensions? It will be a bit confusing whether an object satisfies an interface or not.

Eugene OZ

unread,
Sep 16, 2014, 4:53:54 AM9/16/14
to golan...@googlegroups.com, zhang...@gmail.com
2. if the API owner evolves it, it might conflict with your own extensions)

If signatures of methods will not be changed, all should be fine.

1. you can't share code

Hm. Even more, compiler will not be sure which implementation should be "first" or "overridden". Same as with multiple inheritance. Thanks for that clarification, I have no more questions :) 

Thomas Bushnell, BSG

unread,
Sep 16, 2014, 2:14:46 PM9/16/14
to Jesse McNelis, sleepy, golang-nuts
I disagree quite strongly; it is frequently more expressive to use a method rather than a function even though you have no intention of it ever being involved with an interface. See, for example, the regexp package.

Thomas

 

Rob Pike

unread,
Sep 16, 2014, 2:33:58 PM9/16/14
to Thomas Bushnell, BSG, Jesse McNelis, sleepy, golang-nuts
I agree with Thomas here. The decision to make an operation a method
or a function depends on many factors and cannot be reduced to the
binary decision, "interface or not".

-rob
Reply all
Reply to author
Forward
0 new messages