News for hackers. Stuff that matters.
Re:Golang concepts from an OOP point of view by chimeracoder on Monday September 12, 2016 @03:24PM (#12482827)
> This is a discovery process, I'm writing this document to help myself understanding golang and maybe help others.

First: I took a brief look through this, and I didn't see anything that jumped out as wrong. It's a pretty comprehensive document, especially for someone who says they're just starting out, so kudos to James for writing it!

That said, from my experience in teaching Go classes and workshops for beginners, comparing embedding to inheritance is usually a bad idea. It's not that there aren't similarities, but in my experience it prompts new Go programmers to write unidiomatic Go code when they think of embedding in that way. They end up embedded structs the way they'd use inheritance in object-oriented languages, and since Go isn't really intended as an object-oriented language, it makes for unidiomatic code.

The main use cases of inheritance in OOP are accomplished by interfaces in Go, not struct embedding. But at the same time, the main benefits of embedding come from embedding interfaces - embedding structs is almost an afterthought in the language. In fact, I tend to advise people against embedding structs altogether. There are a few cases where it's worthwhile to embed structs, but the use case for embedding interfaces is much more powerful.

My advice for Go beginners: use interfaces more than you think you need to, and forget that struct embedding is even possible. This rule of thumb helps to write more idiomatic Go code when you're just getting started, before you have a feel for what that really means.

Re:Golang concepts from an OOP point of view by catnaroek on Monday September 12, 2016 @06:59PM (#12484362)
Go discourages classical inheritance, but otherwise it seems pretty object-oriented to me. Interfaces are object types. The only operation they support is calling methods. That's pretty much what objects are: self-contained entities with internal state (fields) and externally visible behavior (methods).

If anything, C++ is less object-oriented than Go, and more oriented towards abstract data types (which C++ programmers call “concepts”).

Re:Golang concepts from an OOP point of view by aikah on Tuesday September 13, 2016 @08:33AM (#12487542)
> Go discourages classical inheritance,

Go makes classic inheritance impossible, it is a bit more than discouraging it.

Re:Golang concepts from an OOP point of view by catnaroek on Tuesday September 13, 2016 @12:46PM (#12490016)
Go might not provide built-in support for classical inheritance, but that doesn't prevent you from rolling your own:

(0) Embed base structs.

(1) Implement non-overridden methods as redirected calls to base struct methods.

(2) Implement overridden method calls however you wish.

What Go doesn't make possible is tying inheritance to subtyping, like Java and C++ do. And this is a very good thing.

Re:Golang concepts from an OOP point of view by aikah on Wednesday September 14, 2016 @07:29AM (#12495779)
> Go might not provide built-in support for classical inheritance, but that doesn't prevent you from rolling your own:

What you described is not inheritance. If you pass your "inherited" type to a function that expect the "parent" type it will not compile. There is no inheritance in Go, and you cannot roll you own.

> What Go doesn't make possible is tying inheritance to subtyping

There is no subtying whatsoever in Go to begin with. There is no point in "inheritance" if it is not polymorphic. What you just did is create a new type. that is not inheritance in a statically typed language.

Re:Golang concepts from an OOP point of view by catnaroek on Wednesday September 14, 2016 @08:56AM (#12496336)
> What you described is not inheritance. If you pass your "inherited" type to a function that expect the "parent" type it will not compile.

That is called “subtyping”, not “inheritance”. Java and C++ happen to conflate the two concepts, but it's perfectly possible to keep them separate.

> There is no subtying whatsoever in Go to begin with.

A struct is a subtype of every interface its methods are compatible with.

Re:Golang concepts from an OOP point of view by aikah on Wednesday September 14, 2016 @04:23PM (#12500926)
It doesn't really matter. Your suggestion is worthless in practice with Go since "your subtype" doesn't enable polymorphism. you can't pass your "subtype" to a function that expect the parent type. You can absolutely pass a sub class in place of a class in a method expecting the class in Java. See the difference ? what you suggested makes absolutely no sense in Go. That's not even subtyping, you just created another struct type with composition.
Re:Golang concepts from an OOP point of view by catnaroek on Wednesday September 14, 2016 @06:50PM (#12501878)
> It doesn't really matter. Your suggestion is worthless in practice with Go since "your subtype" doesn't enable polymorphism.

I never said that struct embedding creates a subtype. I said that it can be used to emulate inheritance (subclassing). Inheritance and subtyping are very different things, and the fact languages like Java and C++ conflate them actually creates several problems. See:

[0] http://www.cs.utexas.edu/~wcook/papers/InheritanceSubtyping9...

[1] http://stackoverflow.com/a/23592298/46571

Re:Golang concepts from an OOP point of view by weberc2 on Monday September 12, 2016 @05:51PM (#12483993)
Interesting. I'm moving away from interfaces and toward plain structs (not consciously, but naturally). I tend to only use interfaces when I want polymorphism, not modularity. This is probably a consequence of me moving away from a mock-all-the-things approach to testing.
Re:Golang concepts from an OOP point of view by skybrian on Monday September 12, 2016 @07:07PM (#12484394)
I recently heard a rule of thumb: "accept interfaces, return structs".

I haven't put it into practice, but it seems like this should give callers enough flexibility to pass in whatever they like.

Re:Golang concepts from an OOP point of view by lloeki on Tuesday September 13, 2016 @02:28AM (#12486006)
Indeed I remember someone laying out some Go good practices (Rob Pike? Andrew Gerrand? damn can't recall) and "accept interfaces, return types" was definitely one of them. Again, a rule of thumb that works very well in most (not all) cases, and, conversely, a code smell.
Re:Golang concepts from an OOP point of view by zalmoxes on Monday September 12, 2016 @10:03PM (#12485148)
That really depends on what you're tying to do. Say you have a Datastore interface, which has some methods like "Create", "Update", "Delete", and a MySQL + an inmem implementation.

You can have `datastore.New() Datastore`, which returns one of the implementations, or you can have `datastore.NewMySQLStore, datastore.NewInMemStore()`. Now you need a different method for each implementation.

Also be careful with returning concrete type, you can run into this issue: https://play.golang.org/p/WHAW1X6elS

Re:Golang concepts from an OOP point of view by patates on Tuesday September 13, 2016 @07:29AM (#12487088)
Wow, that seems like a big issue. Is this accepted as a bug and being worked on or yet another feature?
Re:Golang concepts from an OOP point of view by weberc2 on Tuesday September 13, 2016 @11:31AM (#12489133)
It's not a bug. Interfaces are reference types. In this case, the interface is implemented by a pointer type. The interface can be thought of as a pointer to a nil pointer, but the "interface pointer" itself is not nil.

This is a tricky concept until you learn that interfaces are reference types.

Here's a simplified version of the previous example that illustrates this concept: https://play.golang.org/p/pODBgaHXq5

Re:Golang concepts from an OOP point of view by weberc2 on Tuesday September 13, 2016 @11:44AM (#12489298)
Hmm, I'm not sure that rule of thumb is very good. I think a better one would be "accept interfaces when you want polymorphism". Often I have a very high degree of confidence that your caller will never want to pass a different implementation, and creating the extra interface for an improbably hypothetical situation just isn't worth my time? I'm not making any statements here, just wondering out loud.
Re:Golang concepts from an OOP point of view by solipsism on Monday September 12, 2016 @09:20PM (#12485020)
Toward what kind of testing, mind sharing?
Re:Golang concepts from an OOP point of view by weberc2 on Tuesday September 13, 2016 @11:08AM (#12488915)
I'm not sure that there is a name for it, but I construct my unit with its real dependencies (except for I/O or IPC). I've found that mocking ends up tightly coupling your tests to the implementation (not the behavior) of your unit. This means changes to your unit's implementation (that don't change its behavior) create a bunch of test failures. Also, mocking in Go isn't as easy as in Python, so even installing the mocks is a bit of work.
Re:Golang concepts from an OOP point of view by ratstew on Tuesday September 13, 2016 @08:12AM (#12487391)
I just want to point out that embedding structs does not look like an afterthought at all, the Plan 9 C compilers had a feature akin to it for ages.

http://plan9.bell-labs.com/sys/doc/comp.html

Re:Golang concepts from an OOP point of view by oelmekki on Tuesday September 13, 2016 @06:28AM (#12486816)
Is embedding interfaces still composition, in your opinion? And if not, does this means you recommend not using composition?