Tuesday, February 17, 2015

You Don't Like Google's Go Because You Are Small

When you look at Google's presentations about Go, they are not shy about it. Go is about very smart people at Google solving very BIG problems. They know best. If you don't like Go, then you are small and are solving small problems. If you were big (or smart), you would surely like it.

For example, you might naively think that printing the greater of two numbers should be as simple as
  std::cout << max(b(),c())
That is because you think small. What you really should want is:
  t1 := b()
  if t2 := c(); t1 < t2 {
    t1 = t2
  } 
  fmt.Print( t1 )
Isn't it much better? We didn't have to type all those extra semicolons that were killing productivity before. If you don't like it, you are small.

If you wanted to extract an attribute of an optional parameter, you may be used to typing something like:
a = p ? p->a : 0;
or even:
a = p && p->a
You just make me sad because obviously what you really want is:
a = 0
if p != nil {
  a = p->a
}
It is so much more readable. Trust me, you don't need the ternary operator "?:". It is too complex for you, with your small mind. The creators of Go know better. You also don't need macros or templates, or you might accidentally try to abstract something like "max()" and get confused.

Collections? Don't make me laugh. The only ones you will ever need (or can comprehend in your small mind) are arrays and hash tables. But don't worry about the actual hash function used - you are not allowed to know about it or modify it. Why would you ever care about it, anyway, when everybody knows that practically any hash function always generates perfect results. Or at least, any hash function you could come up with.

If you really, really, are deluded enough to believe you need a different collection, be prepared to remember how you coded in 1987 in C, except you don't have macros, so all typecasts are explicit. Who cares about typecasts anyway, when you are solving really BIIIG problems.

Oh, forgot to mention, "range" doesn't work for your silly little custom data structures, so you better give them up.

Function overloading based on type you ask? Stop with your complaining! You don't need it. People much smarter than you have decided that you will never ever need such a complicated feature in a programming language. Function with the same name performing different operations based on the type of the arguments?? This is insanity. Way too confusing for you anyway. So, this, naturally does not compile:

func add ( a int, b int ) int {
    return a + b
}

func add ( a string, b string ) string { // ERROR!!
    return a + "+" + b
}
(Yes, it is a meaningless example, but that is just to show that function overloading is meaningless anyway!)

Oops, forgot to mention. You might end up needing something like that in a very obscure corner case which is referred by computer scientists as "calling methods of objects". So, in fact, you do have function overloading, but the syntax is much more simple, intuitive and self consistent than that nonsense above. Here it is:

type Int int
func (a Int) add ( b Int ) Int {
    return a + b
}

type String string
func (a String) add ( b String ) String {
    return a + "+" + b
}

func test () {
    var a Int = 0
    b := a.add( 10 )
    var c String = "aa"
    d := c.add( "cc" )
}
It does work, try it. And is so much better than what you may be used to in primitive languages like C++, Java, C#, etc. But you with your small mind cannot be expected to appreciate the beauty.

Interfaces you ask? I am glad you asked. Interfaces are indeed extremely important, so Go has lots of stuff about interfaces. But you don't want to declare them. No, no, no, that would be too hard. God forbid that you wanted to implement "interface Writer" by having to actually type "implements Writer". That is crazy talk. It is much better to just write scattered methods here and there and if they don't happen to match the interface signature because you missed a return type, you get the error in a completely different source file. That is big thinking.

Why should the compiler go to all the trouble of validating an interface implementation when you, the programmer, can do it manually? Compiler time is expensive if you are solving big problems.

Virtual functions? Don't be ridiculous. Who needs that... If you are that stuck up on them, you small minded freak, you can emulate them with interfaces, because you typing is much better than the compiler doing it. Besides, virtual functions are overrated.

And finally, variable case. The big brains decided that typing "export" is too much when solving big problems, so just capitalize the identifier. That alone will probably cause at least 30% increase in productivity.  Of course, don't forget to rename things if you decide they are not public. It is much easier than deleting a keyword, besides you cannot be trusted to follow a coding style, so it is better to enforce at the language level. Same with braces and semicolons.

Good luck in the wonderful world of Go!

-- Update

My blog post got like a 100 views, which is amazing, so I decided I should add a clarification. I don't "hate" Go, I think there is lot there to like (static typing, precise garbage collection, true closures, fast interfaces, sane module system, etc), and that is precisely why its big failings bother me even more.

I view Go as a huge wasted opportunity. How often does a new semi-successful language backed by a successful company appear? Google squandered it through something which looks very much like arrogance.

As it is now, unfortunately Go is little more than an incredible runtime library: very efficient green threads and a precise garbage collector. Someone might port Java to that runtime and reap all of the benefits.