Why no "class" keyword in Go?

1,140 views
Skip to first unread message

ber...@nimblic.com

unread,
Aug 20, 2014, 10:04:33 PM8/20/14
to golan...@googlegroups.com
I'm new to Go. It seems to me that it complicates things by simply not allowing us to define classes like in most other language. Am I missing something fundamental here?

For instance, here's how to declare a "class" in Go.


type
MyClass struct {
 
var name string
 
var id  integer
}


func
(c *MyClass) DoSomethingWithName() error {
  c
.name = "foo"
}


func
(c *MyClass) DoSomethingWithId() error {
  c
.id = "1010"
}



Why didn't the designer simply encapsulate that into a proper class?
Eg: 

class MyClass {
 
var name string
 
var id  integer
 
DoSomethingWithName() error {
    name
= "foo"
 
}
 
DoSomethingWithId() error {
    id
= "1010"
 
}
}

vkojo...@gmail.com

unread,
Aug 21, 2014, 10:50:05 AM8/21/14
to golan...@googlegroups.com
Probably due to:

type Foo int

fun
(f Foo) stuff() {}


receivers can be anything, not just structs

Aram Hăvărneanu

unread,
Aug 21, 2014, 10:53:20 AM8/21/14
to vkojo...@gmail.com, golang-nuts
Methods can be defined in any numbers of files, not just a single file.

--
Aram Hăvărneanu

Qian Qiao

unread,
Aug 21, 2014, 11:10:27 AM8/21/14
to ber...@nimblic.com, golan...@googlegroups.com
I invite you to read this: https://golang.org/doc/faq#Is_Go_an_object-oriented_language

Answers a lot of question that you might have.

-- Joe



--
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.

andrewc...@gmail.com

unread,
Aug 21, 2014, 8:52:56 PM8/21/14
to golan...@googlegroups.com
I don't see any advantage of the class example over the Go example. Can you give a concrete example of how it  "complicates things"? What you are referring to is purely syntax which just just personal preference. I think your approach is less general because it means all methods must be in the same file.

 When introducing inheritance or other things, there may be different arguments. But if you suggest those changes, you will come against strong opinions on why the design is as it is.

Andrew Gerrand

unread,
Aug 21, 2014, 9:01:09 PM8/21/14
to ber...@nimblic.com, golang-nuts

On 21 August 2014 12:04, <ber...@nimblic.com> wrote:
Why didn't the designer simply encapsulate that into a proper class?

Why should they? You haven't provided any rationale.

You should take a look at this talk that I wrote:
(Use the left/right arrows to navigate. There's a video linked on the second slide, too.)

In the talk I discuss my initial reaction to Go's design, and how I came to appreciate what _isn't_ there as much as what is. Check it out.

Andrew

Bernard Duchesne

unread,
Aug 21, 2014, 9:09:01 PM8/21/14
to golan...@googlegroups.com, andrewc...@gmail.com
It complicates things as it doesn't nicely package a class into one conceptual "block". You also have to add the redundant target struct or type in each function signature and inside each function you need to refer to the the target object explicitely. This all adds to a less readable code overall.

Using 'class' doesn't require you to have everything into one file. Other statically typed languages offer ways to add methods to existing classes, in different files. In Scala you can use "implicit conversion" and in C# you can use "extension methods". The C# approach is more elegant. Simpler still is to allow multiple "class" definitions, each adds to/redefines the previous definition. That's what Ruby does. Yes Ruby is dynamic but this principle could be applied to a statically typed language.

Andrew Gerrand

unread,
Aug 21, 2014, 9:12:55 PM8/21/14
to Bernard Duchesne, golang-nuts, Andrew Chambers

On 22 August 2014 11:09, Bernard Duchesne <ber...@nimblic.com> wrote:
It complicates things as it doesn't nicely package a class into one conceptual "block". You also have to add the redundant target struct or type in each function signature and inside each function you need to refer to the the target object explicitely. This all adds to a less readable code overall.

Using 'class' doesn't require you to have everything into one file. Other statically typed languages offer ways to add methods to existing classes, in different files. In Scala you can use "implicit conversion" and in C# you can use "extension methods". The C# approach is more elegant. Simpler still is to allow multiple "class" definitions, each adds to/redefines the previous definition. That's what Ruby does. Yes Ruby is dynamic but this principle could be applied to a statically typed language.

You really need to spend some more time with Go before writing off its design like this.

In addition to my talk, you should read this:

Andrew

Andrew Gerrand

unread,
Aug 21, 2014, 9:18:41 PM8/21/14
to Bernard Duchesne, golang-nuts, Andrew Chambers
On 22 August 2014 11:09, Bernard Duchesne <ber...@nimblic.com> wrote:
It complicates things as it doesn't nicely package a class into one conceptual "block".

It simplifies things because it doesn't force you to conflate your data structures and code by packaging them into one conceptual "block".

A type is a type. A method is a function that takes a type as its first parameter (the receiver parameter).
 
Compared to Go's type system, classes are much more complicated. Compare Go's language specification to that of any language that includes classes.

You also have to add the redundant target struct or type in each function signature and inside each function you need to refer to the the target object explicitely.

Methods are just functions. Functions take arguments. Arguments have types. It is not redundant to specify a function's arguments.

Go favours being explicit over being implicit. That aids readability.
It also aids in refactoring: I can turn a function into a method with a few keystrokes (or vice versa).

This all adds to a less readable code overall.

That's your opinion. I find Go to be the most readable language I have used, and many others agree.

Andrew

andrewc...@gmail.com

unread,
Aug 21, 2014, 9:26:21 PM8/21/14
to golan...@googlegroups.com, andrewc...@gmail.com
I would argue a struct is for representing data, not encapsulating concepts.

Packages provide a conceptual boundary.
Function provide operations on data.
Structs provide a data representation.
Interfaces provide polymorphism and extensibility.

This is closer to functional programming than object oriented.

Shawn Milochik

unread,
Aug 21, 2014, 9:34:50 PM8/21/14
to golan...@googlegroups.com
The two most helpful things I can say are:


2. Write a thousand or two lines of Go. Maybe do the tour (http://tour.golang.org/#1). Then, when you have a feel for the language, see what you think.


Dan Kortschak

unread,
Aug 21, 2014, 9:35:11 PM8/21/14
to Bernard Duchesne, golan...@googlegroups.com, andrewc...@gmail.com
On Thu, 2014-08-21 at 18:09 -0700, Bernard Duchesne wrote:
> It complicates things as it doesn't nicely package a class into one
> conceptual "block".

Conception happens in the mind, not the text editor.

> You also have to add the redundant target struct or type in each
> function signature and inside each function you need to refer to the
> the target object explicitely. This all adds to a less readable code
> overall.

Readability is in part a very personal thing. I find reading java and C#
with their class definitions very taxing.

> Using 'class' doesn't require you to have everything into one file.
> Other statically typed languages offer ways to add methods to existing
> classes, in different files. In Scala you can use "implicit
> conversion" and in C# you can use "extension methods". The C# approach
> is more elegant. Simpler still is to allow multiple "class"
> definitions, each adds to/redefines the previous definition. That's
> what Ruby does. Yes Ruby is dynamic but this principle could be
> applied to a statically typed language.
>
This all sounds far more complicated than what we have now.

andrewc...@gmail.com

unread,
Aug 21, 2014, 9:57:00 PM8/21/14
to golan...@googlegroups.com, andrewc...@gmail.com
To take my reply further, one problem with languages like java is they combine all these concepts into classes. The problem with this is not everything is an object.

e.g. writing some code in java for dealing with time. Say our requirements are:

we want a way to wait an amount of time.
we want a way to get the current unix time.

In Go the concept is "time".
The data is type TimeUnit
The operations are wait, and getCurrentTime.

we can write this as:

Package "time"

type TimeUnit int

func Wait(t TimeUnit) {...}

func GetCurrent() TimeUnit {...}

In java we are forced to make:
A class with only static methods, because they mashed concept with Objects and classes.
Next we are forced to make a class with no methods to represent TimeUnit because it must be a class even though we intend for it to represent data only.

Class TimeUnit {
   int amount;
   //A class with no methods? java combines data and classes in a nonsense way.
}

Class Time {
   //A class with only static methods? java forces a concept to also be a class.
   public static void Wait(TimeUnit t) {...}
   Public static TimeUnit GetCurrentTime() {...}
}

Go just has a more general approach that allows more concepts to be represented cleanly (including OO concepts). Go is not based around "Everything is a class". It just so happens Go allows you to use a style similar to java as well as other styles.

rogerjd

unread,
Aug 21, 2014, 11:07:57 PM8/21/14
to golan...@googlegroups.com
I am very happy they had the insight and courage not to make it like other languages.
Roger

adam

unread,
Aug 21, 2014, 11:59:54 PM8/21/14
to golan...@googlegroups.com, andrewc...@gmail.com
A class is not necessarily an object. When referring to static methods the class should be consider as just a container, next being the package. There is nothing wrong with bundling the static methods within the class of the object that would most interact with them. I don't see how bundling static methods within a class is any different from bundling functions within a package.

Benjamin Measures

unread,
Aug 22, 2014, 5:18:28 AM8/22/14
to golan...@googlegroups.com
On Thursday, 21 August 2014 03:04:33 UTC+1, Bernard Duchesne wrote:
I'm new to Go. It seems to me that it complicates things by simply not allowing us to define classes like in most other language. Am I missing something fundamental here?

Go favours composition over inheritance[1].

Inheritance is a fragile disaster[2]. Class syntax was formed with inheritance in mind. To do composition with classes requires extraordinary "tricks" (and mindless boilerplate).  Classes have got to go.

Jan Mercl

unread,
Aug 22, 2014, 5:33:33 AM8/22/14
to ber...@nimblic.com, golang-nuts
How would the proposal translate

type MyInt int

func (i MyInt) method() {...}

var v MyInt = 42

func foo(i MyInt) {...}


if baz() { foo(314) }

?

And among other reasons: Easy and unambiguous grep for the method is
no more available with the proposal.

-j

Bernard Duchesne

unread,
Aug 22, 2014, 5:43:13 AM8/22/14
to golan...@googlegroups.com, ber...@nimblic.com
@jan Merci: It's not a proposal, just a question and I used pseudo code to explain it.

@andrewc: Thanks for the expanded answers. I can see the point. It's like many things in Go right now, I will reserve final judgement after I've spent a lot more time with it. I've started rewriting my Node.js/Javascript code to Go.

Thanks everyone.

Jesper Louis Andersen

unread,
Aug 22, 2014, 6:17:14 AM8/22/14
to Bernard Duchesne, golang-nuts, andrewc...@gmail.com

On Fri, Aug 22, 2014 at 3:09 AM, Bernard Duchesne <ber...@nimblic.com> wrote:
It complicates things as it doesn't nicely package a class into one conceptual "block". You also have to add the redundant target struct or type in each function signature and inside each function you need to refer to the the target object explicitely. This all adds to a less readable code overall.

The choice is really one of ideology. The basic class concept can be tracked to at least Java and C#, but there is a whole slew of object oriented languages which follow the style of Go. It is clear that the Go authors drew ideas from those languages. The redundancy is a trade-off, but it does buy you certain things:

* The language is simpler syntactically
* Given a method, its scope is clear because the object which the method is attached to is readily available.
* You can add methods to any type. Note functions are types as well! 
* There is a nice way to further extend existing types with new methods without relying on concepts like inheritance, extension methods or implicit conversions. All these tools are requirements for programming-in-the-large since other people might have written the base structure you are extending.

Of course, there are other ways to achieve this, of which you mention a few, but the Go approach is remarkably succinct and consistent. The price you pay is a bit of redundancy.


--
J.
Reply all
Reply to author
Forward
0 new messages