Re: [go-nuts] C++ virtual functions analog in Go

1,590 views
Skip to first unread message

Aaron France

unread,
May 6, 2013, 5:51:47 PM5/6/13
to drago....@gmail.com, golang-nuts
Hi,

Possible type embedding will get you some of the way there. http://play.golang.org/p/BgnvwqjbxC

Regards,
Aaron



On Mon, May 6, 2013 at 11:12 PM, <drago....@gmail.com> wrote:
Hi,
I know Go is not true OOP language, but is there any way for "base class" to call method of "derivated class" polyformically, just like C++ virtual methods?
Thank you

--
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/groups/opt_out.
 
 

Alexei Sholik

unread,
May 6, 2013, 6:11:39 PM5/6/13
to drago....@gmail.com, golang-nuts
There is no inheritance in Go, so what you're trying to do is not useful.

Look at interfaces. In your function, you specify an argument to be of type YourInterface. Then you can path any object that implements methods defined in the interface to that function. This workflow doesn't involve constructing type hierarchies, like you would do in C++.

Type embedding is mostly useful to share functionality between structs. Again, there is no explicit Superstruct -> Substruct relation. Instead, embedded types are more like compile-time mixins.


On Tue, May 7, 2013 at 1:05 AM, <drago....@gmail.com> wrote:
Well, that is not what I am looking for. Let me show you a C++ program example:



--
Best regards
Alexei Sholik

Alexei Sholik

unread,
May 6, 2013, 6:15:16 PM5/6/13
to drago....@gmail.com, golang-nuts
To clarify, the example of using interfaces with function arguments was just an arbitrary example I came up with. You can create ordinary variables of interface types. Such a variable can hold any object that implements the interface. And calling a method on the variable will dispatch to the method on the actual object stored in that variable.

Gerard

unread,
May 6, 2013, 6:18:57 PM5/6/13
to golan...@googlegroups.com, drago....@gmail.com

Tad Glines

unread,
May 6, 2013, 6:33:17 PM5/6/13
to golan...@googlegroups.com
I think this is what you might be looking for: http://play.golang.org/p/zuhZzXZ6L4

Your example in C++ is similar to an abstract class in Java. You want to define some/most of the behavior in a base class and then define the rest in derived classes. This is possible in Go, but requires (as far as I understand it) that the virtual/abstract methods be implemented in the base "class". You can just stub them out with a panic, but you won't get the com;ile time checking you get with Java or C++.

-Tad

On Mon, May 6, 2013 at 3:19 PM, <drago....@gmail.com> wrote:
As I am evaluating Go for a project of mine, I was wondering how one can implement some of the GoF patterns, namely:
http://sourcemaking.com/design_patterns/template_method

Peter Bourgon

unread,
May 6, 2013, 6:43:26 PM5/6/13
to drago....@gmail.com, golang-nuts
On Tue, May 7, 2013 at 12:19 AM, <drago....@gmail.com> wrote:
> As I am evaluating Go for a project of mine, I was wondering how one can
> implement some of the GoF patterns, namely:
> http://sourcemaking.com/design_patterns/template_method

What specific/concrete problem is the template method design pattern
helping to solve, in your project?


> 07 май 2013, вторник, 01:11:39 UTC+3, alco написа:
>>

Tad Glines

unread,
May 6, 2013, 6:56:41 PM5/6/13
to golan...@googlegroups.com
On Mon, May 6, 2013 at 3:48 PM, <drago....@gmail.com> wrote:
Tad, yes I want exactly " to define some/most of the behavior in a base class and then define the rest in derived classes". 
But your example doesn't do that. I think there is no machinery in Go for this at all. 
It is OK, this kind of functionality can be expressed in Derivated classes alone, but with code duplication I am afraid. 

Look at my example again. What I have shown you is (almost) exactly what you want. method B is defined only once, but is available in both base and derived. methodA is defined in both base and derived, but the base implementation can be stubbed out. The only reason it is defined in base is so that it can be overridden by derived.

-Tad

Tad Glines

unread,
May 6, 2013, 7:18:27 PM5/6/13
to golan...@googlegroups.com
Sigh... Yes, your right.
This is what I get for trying to do two things at once. I was actually somewhat surprised when my "example" appeared to work.

Here's an alternative pattern: http://play.golang.org/p/xmii1I2mpS
It inverts the roles a bit. It's not quite as neat as in C++ or Java, but can get the job done.

-Tad

On Mon, May 6, 2013 at 4:03 PM, <drago....@gmail.com> wrote:
Tad, you example is ecvivalent to: http://play.golang.org/p/2_JSbYLSJn
If you though to call methodB() then the result is: http://play.golang.org/p/XeL-iHT9d2
--

Jesse McNelis

unread,
May 6, 2013, 7:28:35 PM5/6/13
to drago....@gmail.com, golang-nuts


On 07/05/2013 8:49 AM, <drago....@gmail.com> wrote:
>
> Tad, yes I want exactly " to define some/most of the behavior in a base class and then define the rest in derived classes". 

Go doesn't have the concept of a base class so this is an impossible request.
Inheritance groups a number of features together, polymorphism and code reuse.
Go uses interfaces for polymorphism, and composition(embedding) and functions for code reuse.

Instead of defining a 'base class'  define an interface and write a function that takes that interface value and does the concrete thing you want to do.

implement that interface for any type you want to be able to share that code with.

Jsor

unread,
May 7, 2013, 5:44:25 AM5/7/13
to golan...@googlegroups.com, drago....@gmail.com, jes...@jessta.id.au
While (the lack of) virtual classes in Go have been discussed, it seems you just want to implement a Template pattern?

If so, here's one possibility:


The gist is, since functions can be passed around like variables in Go, and since closures maintain state, you can effectively treat an exported (Capital) variable of type <func(argument) returnval> as if it were just a function the method had any way, so long as you take care to initialize it.

In this way, you can have a function that does "static" work (i.e. like what the base class does), and then have another function that you can swap out that does problem-specific work (like a virtual class). I wrote a K-Nearest-Numbers program that, while it didn't do this exactly, took the Distance function in as a parameter to the KNN function, allowing you to decide what kind of distance metric you wanted to use for determining the nearest neighbors.

Of course, one thing to be careful with is that any package user can reassign that function to another one with the signature func() int, if that's unacceptable you can not export the variable and wrap it like so:


Or, if the "problem specific" function doesn't need to be visible outside the package at all, you can always do:

Jsor

unread,
May 7, 2013, 5:53:48 AM5/7/13
to golan...@googlegroups.com, drago....@gmail.com, jes...@jessta.id.au
Oh, also, if you need you faux-"derived" class to have its own set of local variables to maintain state, closures do that too:


(See the new "varer" I added)

It's not exactly the same, you can only really retrieve those values outside the generated function if you do stuff with returning multiple functions from the closure or other trickery, but it should give you a pretty good approximation of what you're used to.

Jsor

unread,
May 7, 2013, 5:58:19 AM5/7/13
to golan...@googlegroups.com, drago....@gmail.com, jes...@jessta.id.au
This is what I mean by "tricks with returning multiple functions":


(Okay, I'll stop spamming now)

Jsor

unread,
May 7, 2013, 6:06:27 AM5/7/13
to golan...@googlegroups.com, drago....@gmail.com, jes...@jessta.id.au
Crap, obviously I meant "derived" instead of "virtual" class (or, alternatively, I meant "virtual function"), and I meant "function that class(/struct) had anyway" rather than "function that method had anyway". In that last example I posted I probably should have chosen a clearer name for the int in the Setter function that "a" (since that has a name conflict with the struct pointer we're passing in). Oh well.

Seriously stopping posting this time.

Aaron France

unread,
May 7, 2013, 6:31:03 AM5/7/13
to Jsor, golang-nuts, Dragomir Ivanov, jes...@jessta.id.au
One must also ask of your sanity of wanting to call a derived method from a base class.

-Aaron


--

Alexei Sholik

unread,
May 7, 2013, 6:53:49 AM5/7/13
to Jsor, golang-nuts, Dragomir Ivanov, jes...@jessta.id.au
Jsor, what you've described here looks more like a strategy pattern.

Anyway, the original question does not have a correct answer in Go. The author needs to specify the problem he wants to solve. Simply asking how to implement virtual methods and derived classes in Go is not the way to go with Go.


--
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/groups/opt_out.
 
 

Alexei Sholik

unread,
May 7, 2013, 6:56:22 AM5/7/13
to Aaron France, Jsor, golang-nuts, Dragomir Ivanov, jes...@jessta.id.au
> One must also ask of your sanity of wanting to call a derived method from a base class.

There is nothing wrong with that. It is common to have some methods implemented in the base class that may call to other virtual methods. Any virtual method could potentially be reimplemented in a derived class. The actual implementation used depends on `this`.

Aaron France

unread,
May 7, 2013, 7:06:26 AM5/7/13
to Alexei Sholik, Jsor, golang-nuts, Dragomir Ivanov, jes...@jessta.id.au
It's the relationship which seems weird, do people *really* need this behaviour or is it a side effect of what inheritance makes us believe we need?

Alexei Sholik

unread,
May 7, 2013, 8:24:21 AM5/7/13
to Aaron France, Jsor, golang-nuts, Dragomir Ivanov, jes...@jessta.id.au
> It's the relationship which seems weird, do people *really* need this behaviour or is it a side effect of what inheritance makes us believe we need?

No point arguing whether using composition over inheritance would be better on this list: Go doesn't have inheritance. But it is a fact that main-stream languages like C++, Java, C# mostly rely on inheritance, although there are many design patterns from the Big Four's book that show the prevalence of composition in some situations.

Craig Mason-Jones

unread,
May 7, 2013, 6:58:35 PM5/7/13
to golan...@googlegroups.com, drago....@gmail.com
If I'm understanding the Template Design Method directly, it's summed up as "Don't call us, we'll call you". In C++ or more object-orientated languages than Go, inheritance and virtual functions is a valid way to implement this. But in Go (or indeed in C or C++ if you're so inclined), it's very easily implemented with function parameters:

http://play.golang.org/p/JY3YXQlmS0

I think the Strategy Design Pattern is more of a match for an interface.

With Go 1.1 we've got Method Values, so you can also pass a bound method value as a function parameter. (You could do that previously with closures).

I think the important thing is to distinguish between the essential nature of the pattern, and the implementation details that are specific to a particular language or class of languages.

C

Dan Kortschak

unread,
May 7, 2013, 8:16:51 PM5/7/13
to Alexei Sholik, Aaron France, Jsor, golang-nuts, Dragomir Ivanov, jes...@jessta.id.au
This kind of argument is not valid. By analogy, take for example the reflexive verb 'pattern' is widely used in the Spanish speaking world. In English, this is not the case, and using that 'pattern' in English is likely to lead to confusion or humour.

In short, idioms don't necessarily translate.

Chris Hines

unread,
May 7, 2013, 8:28:40 PM5/7/13
to golan...@googlegroups.com, drago....@gmail.com
It is ugly, but you can roll your own virtual functions by manually creating the function table and populating it with the proper method values or closures.

A variant of Tad's code showing the technique: http://play.golang.org/p/vlF-304jOB

Maybe someone can simplify this a bit to make it more palatable, but it's not going to approach the C++ or Java syntax because Go doesn't have direct support for the concept.

On Monday, May 6, 2013 6:48:57 PM UTC-4, drago....@gmail.com wrote:
Tad, yes I want exactly " to define some/most of the behavior in a base class and then define the rest in derived classes". 
But your example doesn't do that. I think there is no machinery in Go for this at all. 
It is OK, this kind of functionality can be expressed in Derivated classes alone, but with code duplication I am afraid. 

Aaron France

unread,
May 8, 2013, 4:48:02 AM5/8/13
to golan...@googlegroups.com, drago....@gmail.com
Hi,


-Aaron
Reply all
Reply to author
Forward
0 new messages