Go Object Oriented Design

851 views
Skip to first unread message

Nathan Youngman

unread,
Jan 14, 2013, 11:36:25 PM1/14/13
to golan...@googlegroups.com
We've seen a fair amount written about concurrency in Go, but I really wanted to spend some time digging into Go's object model. This article is a result, and covers embedding, interfaces and packages as compared to classical languages like Ruby. I hope that some people find the examples helpful.


If you notice any errors, please let me know (here). Thanks!

bryanturley

unread,
Jan 15, 2013, 2:22:43 AM1/15/13
to golan...@googlegroups.com


On Monday, January 14, 2013 10:36:25 PM UTC-6, Nathan Youngman wrote:
We've seen a fair amount written about concurrency in Go, but I really wanted to spend some time digging into Go's object model. This article is a result, and covers embedding, interfaces and packages as compared to classical languages like Ruby. I hope that some people find the examples helpful.

Ruby is a classical langauge?
Does that mean I am a dinosaur?

Nathan Youngman

unread,
Jan 15, 2013, 2:53:49 AM1/15/13
to bryanturley, golan...@googlegroups.com


On Tuesday, January 15, 2013, bryanturley wrote:

Ruby is a classical langauge?
Does that mean I am a dinosaur?



Hah. I meant, Classical, as in it uses classes. I don't believe there is a correlation between the Ruby object model and whether or not you are a dinosaur. :-P

Nathan.


--
Nathan Youngman
Email: n...@nathany.com
Web: http://www.nathany.com

Kevin Gillette

unread,
Jan 15, 2013, 3:07:13 AM1/15/13
to golan...@googlegroups.com
If we called it a classy language, does that make you a slob?

vustyle

unread,
Jan 15, 2013, 4:16:22 AM1/15/13
to golan...@googlegroups.com
Thank you. Good article. VeryclearusageofgoClass

André Moraes

unread,
Jan 15, 2013, 6:02:50 AM1/15/13
to Nathan Youngman, golan...@googlegroups.com
"Alternatively, Go provides first-class functions and closures, which
are commonly used for namespacing in languages like JavaScript."

I don't think Go closures should be compared to
(function(require, exports){/*my module*/}(require, exports))

Since this is a hack in JS and Go have namespaces in it's design. In
fact Go namespaces are much better than other alternatives since
nothing is global in it (except some builtin types/functions)


--
André Moraes
http://amoraes.info

Sean Russell

unread,
Jan 15, 2013, 6:43:34 AM1/15/13
to golan...@googlegroups.com
Hi Nathan,


On Monday, January 14, 2013 11:36:25 PM UTC-5, Nathan Youngman wrote:

If you notice any errors, please let me know (here). Thanks!

Just one thing I'm not sure about:

It is possible to override Spares() on Bicycle and still reference the embeddedParts.Spares(). This feels almost like inheritance, but embedding does not provide polymorphism. The receiver of Spares() will always be of type Parts, even when called directly from a Bicycle. 

I read this as "even if you override Spares(), the receiver will be of type Parts." Is this correct?


--- SER

Joey Geralnik

unread,
Jan 15, 2013, 7:41:15 AM1/15/13
to Sean Russell, golan...@googlegroups.com
He meant that the receiver of Parts.Spares will always be a Parts, not a Bicycle, so polymorphism is not possible. See for example http://play.golang.org/p/Be_QCgWju6
--Joey


--
 
 

Nathan Youngman

unread,
Jan 15, 2013, 10:34:23 AM1/15/13
to Sean Russell, golan...@googlegroups.com

I meant to say the receiver of Parts.Spares() will be of type parts when delagated to through Bicyle. It will probably be clearer if I swap some sentences around. Override may not be the best word, because of other connotations in programming languages. 

Thanks for the feedback. FYI, this is what Effective Go has to say on the subject:

"There's an important way in which embedding differs from subclassing. When we embed a type, the methods of that type become methods of the outer type, but when they are invoked the receiver of the method is the inner type, not the outer one. In our example, when the Read method of abufio.ReadWriter is invoked, it has exactly the same effect as the forwarding method written out above; the receiver is the reader field of theReadWriter, not the ReadWriter itself."


Nathan
--
 
   
   M m

Patrick Mylund Nielsen

unread,
Jan 15, 2013, 3:24:08 PM1/15/13
to johns...@gmail.com, golang-nuts
Please google "golang groups error handling". There are numerous threads about error handling, why it is and will stay like it is, and why most Go developers aren't bothered by it, and in fact prefer it.


On Tue, Jan 15, 2013 at 12:30 PM, <johns...@gmail.com> wrote:
Here's a debate on Go

The question is how can you have concurrency without effective error handling?

Is this where Bertrand Meyer's Design by Contract would be most useful?


On Monday, January 14, 2013 11:36:25 PM UTC-5, Nathan Youngman wrote:

--
 
 

Dan Kortschak

unread,
Jan 15, 2013, 3:45:47 PM1/15/13
to golan...@googlegroups.com
Don't people get bored of writing those articles?

Dave Cheney

unread,
Jan 15, 2013, 3:53:00 PM1/15/13
to Dan Kortschak, golan...@googlegroups.com
Meh, after reading I place that article in the 'no press is bad press' category.
> --
>
>

minux

unread,
Jan 15, 2013, 3:55:50 PM1/15/13
to Dave Cheney, Dan Kortschak, golan...@googlegroups.com
On Wed, Jan 16, 2013 at 4:53 AM, Dave Cheney <da...@cheney.net> wrote:
Meh, after reading I place that article in the 'no press is bad press' category.
I'd say the author just pointed out all the points I love about Go even though
he/she strongly thought that one of them was '70 style and out-dated (and i disagree).

Dan Kortschak

unread,
Jan 15, 2013, 3:59:49 PM1/15/13
to Dave Cheney, golan...@googlegroups.com
But continually rehashing the same tired and inaccurate complaints surely must get boring. If they actually had something to add, sure, but they never seem to get beyond, 'have to check every statement', 'I don't like braces', and 'fmt! WTF'.

Dan Kortschak

unread,
Jan 15, 2013, 4:03:53 PM1/15/13
to golan...@googlegroups.com
Yes. People need to understand that languages are principally for communication between people and so, tastes varying, different languages and coding styles will appeal to different people and in different contexts and domains. This class of article really sits along side complaints about cuisine styles.

Dave Cheney

unread,
Jan 15, 2013, 4:06:08 PM1/15/13
to minux, Dan Kortschak, golan...@googlegroups.com
Exactly. My favourite point about this class of article is how they throw stones without providing a modern replacement -- I could equally parry with "exceptions?!? How quaintly 1980's of you". 

The comment about panic being a sneaky exception class private to the runtime shows a clear lack of understanding of the difference between the exceptional, a programming error leading to an uncorrectable bounds check failure at runtime, and the mundane class of errors like io.EOF. 

The continued calls for exception style error handling show a failure to think concurrently. How exactly would you pass an exception between goroutines ? I would imagine it would be some sort of interface value that can be passed via a channel. Oh, wait, we already have that today, it's called error. 

Dave 

Patrick Mylund Nielsen

unread,
Jan 15, 2013, 4:10:21 PM1/15/13
to Dave Cheney, minux, Dan Kortschak, golan...@googlegroups.com
To be fair, asynchronous exceptions do exist in other languages. They're just incredibly dangerous since they can interrupt anything at any point in a thread. Go is much safer and saner in that respect.


--
 
 

Dave Cheney

unread,
Jan 15, 2013, 4:30:05 PM1/15/13
to Patrick Mylund Nielsen, minux, Dan Kortschak, golan...@googlegroups.com
Indeed, I think my point has been made for me. 

I'm honestly surprised pythonistas aren't more upset about gofmt. 

minux

unread,
Jan 15, 2013, 4:48:09 PM1/15/13
to Dave Cheney, Patrick Mylund Nielsen, Dan Kortschak, golan...@googlegroups.com
On Wed, Jan 16, 2013 at 5:30 AM, Dave Cheney <da...@cheney.net> wrote:
I'm honestly surprised pythonistas aren't more upset about gofmt. 
I used to work with C/C++ and Python (although my main language at work
is Verilog).

Coming from a Python & C background, I'd say I really love gofmt partly because
for Python, we already have a rather strict formatting style and gofmt doesn't
add much; and partly because gofmt's style just resembles the C style I've been
using for years (the main difference between Go's idiomatic style and the C style
I used to is Go use CamelCase, and in C, I'm fond of underscores :-) ).

Also, I'm really tired of arguing about which coding style is better.

Nate Finch

unread,
Jan 15, 2013, 5:02:50 PM1/15/13
to golan...@googlegroups.com, minux, Dan Kortschak
I had an epiphany while coding... I no longer have to worry about my code suddenly exiting out of the middle of a method, and how the hell I'll clean up if that happens.

For example:

f := os.Open(foo)
< do stuff with f >

// I know the code will ALWAYS get here
// because no one can throw an exception in the middle
f.Close()

(and yes, I know about defer... this is just an example)

Totally blew my mind that this is actually perfectly safe (as long as I don't return before the close, which is under my own control).

Job van der Zwan

unread,
Jan 15, 2013, 5:14:35 PM1/15/13
to golan...@googlegroups.com, minux, Dan Kortschak
On Tuesday, 15 January 2013 23:02:50 UTC+1, Nate Finch wrote:
// I know the code will ALWAYS get here
// because no one can throw an exception in the middle
f.Close()

Err... I think you should read this.

Ryan Macy

unread,
Jan 15, 2013, 4:41:51 PM1/15/13
to Dave Cheney, Patrick Mylund Nielsen, minux, Dan Kortschak, golan...@googlegroups.com
Dave Cheney wrote:

Indeed, I think my point has been made for me.

I'm honestly surprised pythonistas aren't more upset about gofmt.

On 16/01/2013, at 8:10, Patrick Mylund Nielsen

To be fair, asynchronous exceptions do exist in other languages.
They're just incredibly dangerous since they can interrupt anything
at any point in a thread. Go is much safer and saner in that respect.


On Tue, Jan 15, 2013 at 3:06 PM, Dave Cheney <da...@cheney.net
<mailto:da...@cheney.net>> wrote:

    Exactly. My favourite point about this class of article is how
    they throw stones without providing a modern replacement -- I
    could equally parry with "exceptions?!? How quaintly 1980's of you".

    The comment about panic being a sneaky exception class private to
    the runtime shows a clear lack of understanding of the difference
    between the exceptional, a programming error leading to an
    uncorrectable bounds check failure at runtime, and the mundane
    class of errors like io.EOF.

    The continued calls for exception style error handling show a
    failure to think concurrently. How exactly would you pass an
    exception between goroutines ? I would imagine it would be some
    sort of interface value that can be passed via a channel. Oh,
    wait, we already have that today, it's called error.

    Dave


    On 16/01/2013, at 7:55, minux <minu...@gmail.com
    <mailto:minu...@gmail.com>> wrote:



    On Wed, Jan 16, 2013 at 4:53 AM, Dave Cheney <da...@cheney.net
    <mailto:da...@cheney.net>> wrote:

        Meh, after reading I place that article in the 'no press is
        bad press' category.

    I'd say the author just pointed out all the points I love about
    Go even though
    he/she strongly thought that one of them was '70 style and
    out-dated (and i disagree).


    --




--




I don't mind gofmt and I work with python 60+ hours weekly.

I actually quite like it :)

Nathan Youngman

unread,
Jan 15, 2013, 7:38:58 PM1/15/13
to golan...@googlegroups.com

@jsw Thanks for thoroughly hijacking the thread. :-P I think OO design and error handling are fairly orthogonal, unless you have a particular love for deep exception hierarchies. Which is to say, even if Go had something called exceptions, they would be different than other languages, and people would still have something to complain about. I'm quite happy with how Go does it, hope you find the defer, panic, recover article inspirational.

André, I've removed the line about closers for namespacing, as I've not yet tried it, and I don't imagine it's all that idiomatic.

Sean, I've tweaked the wording for embedding. Hopefully it is a little more clear for future readers.

Thanks for the feedback. I hope to write more Go articles as I learn more about it (write what you learn:-).

Nathan.


On Tuesday, 15 January 2013 17:13:02 UTC-7, johns...@gmail.com wrote:
Job,

Interesting example.  I'll have to read through it tonight.

Cheers,
jsw

Nate Finch

unread,
Jan 15, 2013, 8:52:11 PM1/15/13
to golan...@googlegroups.com, minux, Dan Kortschak
Yeah, I know about panic. But since I never use panic, and stdlib never uses panic (that it doesn't also recover from), then it shouldn't ever be a problem.  And if it is, my app will crash, and I won't care if the file is closed or not.


On Tuesday, January 15, 2013 5:14:35 PM UTC-5, Job van der Zwan wrote:

Patrick Mylund Nielsen

unread,
Jan 15, 2013, 9:04:14 PM1/15/13
to Nate Finch, golang-nuts, minux, Dan Kortschak
I agree. You can assume that nothing will crash randomly in-between a series of functions unless you are doing something silly == bad input to stdlib API. I often use this to lock and unlock a mutex early on, or in the middle of a function, when it is not practical to either split it it up into more, smaller functions, or to wait for deferreds to run.

Compare this with languages where, as long as another thread has the ID of the thread/goroutine, it can throw an exception at any point in the execution of any function or subfunction. (Sure, you could argue that it's up to you to be disciplined about using killThread, but the lack of it aligns nicely with Go's principle that "if you can read some section of your code, you can tell what it does.")


--
 
 

Job van der Zwan

unread,
Jan 17, 2013, 11:01:01 AM1/17/13
to golan...@googlegroups.com, minux, Dan Kortschak
Fair enough - I interpreted "ALWAYS" and "no one can throw an exception" as specifically implying you don't have to worry about other people's code.
Reply all
Reply to author
Forward
0 new messages