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.

83 comments:

  1. I always say that Go is a language designed for PhDs who are too stupid to do anything other than write code at Google.

    Too bad you got flagkilled on HN. Not that I would have commented there though because I'm hellbanned and slowbanned.

    ReplyDelete
  2. I've been developing exclusively in Go and love it. Small implies simple, and it turns out that language simplicity provides a nice benefit that isn't always obvious - productivity. Enjoy generics, virtual functions, exceptions, and the rest of the complex features from other languages. I'll happily continue benefiting from the productivity gains I've found in Go.

    ReplyDelete
    Replies
    1. Could you elaborate on that? (I'm legitimately asking, I want to know why a lot of people favor Go so much)

      Delete
    2. How can small imply simple? What about assembler for AVR?

      Delete
  3. Not getting enough sex?

    ReplyDelete
    Replies
    1. Not getting enough satire?

      Delete
    2. neither! which one are you guys offering?

      Delete
    3. But apparently you do! You enjoy getting fucked by Golang.

      Delete
  4. Is it me or does the first code
    std::cout << max(b(),c())

    look way more concise and desirable than the following verbose version? Does it look more desirable because I think 'small' :)

    ReplyDelete
    Replies
    1. That's the point he's making. It's sarcasm.

      Delete
  5. Interface validation:

    var _ = io.Reader(myType{})

    and voilá, you declared it, and compiler checks it.

    ReplyDelete
  6. For someone that has been struggling with grasping Go for a few days, this is priceless.

    ReplyDelete
  7. Your post is bad, and you should feel bad

    ReplyDelete
  8. You forgot to mention how if you start using Go in your project and start liking it your project automatically becomes Big.

    ReplyDelete
    Replies
    1. Of course it does. That's because you're now writing as much error handling code as primary logic, rather than just putting an exception handler at the top level. It's good to be explicit about error handling, you know.

      Delete
  9. Last post... 2011 -- with this quality, hopefully we won't hear from you again for another 4 years.

    ReplyDelete
    Replies
    1. OP has clearly counted to potato

      Delete
  10. The max function in c does almost exactly the same as the code you wrote in go. Go just doesn't hand you a wrapper function for it..

    #define max(a,b) \
    ({ __typeof__ (a) _a = (a); \
    __typeof__ (b) _b = (b); \
    _a > _b ? _a : _b; })

    Next, lack of collections: go is specifically designed to be a minimal language. Do you really have that much trouble creating a simple 'collection' class...?

    Furthermore, calling methods on objects works 100% when you don't try to call methods on primitives..... You do realize int is a primitive, right?

    Lastly; yes, we all know and have known for 5 years now that Go does not and will not support ternary operators, virtual functions, and function overloading. By the way you forgot generics. Once you add that you'll have pretty much the entire list of common complaints.

    ReplyDelete
    Replies
    1. "Next, lack of collections: go is specifically designed to be a minimal language. Do you really have that much trouble creating a simple 'collection' class...?"

      This is a terrible argument. It means that everyone has to waste time writing this class and each version will be a little different. Which is no biggie until you start using third party code and have to look up how their collections work.

      Delete
    2. "Next, lack of collections: go is specifically designed to be a minimal language. Do you really have that much trouble creating a simple 'collection' class...?"

      The problem is because of the missing parametric polymorphism you have 2 equally terrible choises:

      - either implement the colleaction for each contained type (like ListInt, ListString, etc)

      - or use type casts (in the form of interface{}) and loose all the type safety.

      On a side note, I find the Go's type system severely lacking - it is designed to help the compiler, not for compiler to help you write correct code.

      Delete
    3. It's not just that Go doesn't hand you a wrapper function; Go prevents you from writing a wrapper function. Specifically, you can't write one max() function for all types (unlike C, C++, C#, D, Nim, Python, ...), and you can't write one max() function for each type. Instead, you need to write IntMax and FloatMax and StringMax...

      Oh wait, you can't even write IntMax because integers don't implicitly cast to larger types. You're writing UInt8Max, Int8Max, UInt16Max, Int16Max, etc, for all 10 numeric types. And then you have to be sure to use the right one each time. Granted, the compiler will tell you if you used the wrong one, but that's not so friendly.

      Delete
    4. You are a small thinker... copy-paste is your friend! Here is the code snippit to copy-paste:

      t1 := b()
      if t2 := c(); t1 < t2 {
      t1 = t2
      }

      Delete
    5. "Next, lack of collections: go is specifically designed to be a minimal language. Do you really have that much trouble creating a simple 'collection' class...?"

      No, and neither do the tens or hundreds of thousands of other developers also forced to invent the same wheel because Google didn't bother to fit some to the cart.

      Delete
  11. "you might accidentally try to abstract something ... and get confused" had me laughing so that I wouldn't cry.

    I write Go every day and mostly enjoy it. My biggest pain point is the way the language consistently fights abstraction forcing developers into endless boilerplate.

    ReplyDelete
  12. This completely nails the Google Developer mentality. Google: Where naive, impractical code is written because we still make all of our money on search ads. Oh - and because of that we are better than you.

    ReplyDelete
    Replies
    1. This blog itself is made by google

      Delete
  13. Hey Tzvetan, how long time would it take you to make C++ to search something on Google via simple GET request or modify a GIF image adding a text?

    But I get it, overloading and ternary operators are the big problem.

    1/10 because I replied.

    ReplyDelete
    Replies
    1. Ooh as if libraries don't exist. As you're comparing runtime/external library functionality, right? .... Right?

      Delete
    2. Yes he is. Now how long?

      Delete
    3. @Anonymous: 17", how about you? ;-)

      Delete
  14. Don't forget endless,
    if err != nil {
    return err
    }

    ReplyDelete
  15. Having coded in Go for more than two years, I have the same impression as you, Tzevtan. Go has some appeal, but it has far more hassles that make using it every day a burden. Rust, however, is much more enjoyable.

    ReplyDelete
  16. Brilliant post, but function overloading actually *is* unintuitive and unnecessary. There are loads of programmers out there who will get confused by the fact that double dispatch doesn't work. Also, the lack of overloading doesn't hurt anybody and simplifies the compiler.

    ReplyDelete
    Replies
    1. The point I was trying to make was that Go has function overloading anyway - it is unavoidable. You need to be able to dispatch methods based on the type of "this" and Go does support that. But it is ugly and unintuitive and works only for the first parameter. So, while trying to "simplify" the language, they ended up with a mess.

      Instead of simplifying it, they "stupidified" it.

      Delete
  17. I think that Go is great for small programs. However, around 1k lines of Go, I generally reach for a tool that supports higher levels of abstraction, and I can generally compress 1k lines of Go to 1/10 - 1/2 that in Scala, C++ or Rust.

    It's a great tool for the domain in which it applies, but I feel the same exact way that you do - it should be so much more than its overlords are allowing it to be.

    Who wants to fork it and add generics and type parametric functions?

    ReplyDelete
    Replies
    1. I have a `working` (preview) version of type parametric fuctions:

      A linked list DEMO:
      http://our-gol-842.appspot.com/p/1dhc6VkSPz

      https://groups.google.com/forum/#!topic/golang-dev/_V7_Be-AA38

      Delete
    2. A linked list DEMO:
      http://our-gol-842.appspot.com/p/1dhc6VkSPz

      https://groups.google.com/forum/#!topic/golang-dev/_V7_Be-AA38

      Delete
  18. Don't forget the package management. It's stupid to specify a version of a dependency, you should always use whatever is in master on github.

    ReplyDelete
  19. Go is worst thing happened to IT this century. Everything you can screw up is screwed up. Everything you can't screw up is still screwed up. I mean come on, you need special hack to google about language developed by google retards. It's epic, really.

    Year back I still worked for small company (former startup) which decided that we need to go serious and adopt go (and, apparently, rewrite everything which did or did not needed rewrite). Perfect example was small service (~200 lines of go code) which crashed on daily basis. It's only task was to listen to TCP requests (~300 open connections) and process commands "LOCK ID, TIMEOUT" and "UNLOCK ID". They were unable to fix it for almost an year and when I moved on to greener pastures it was still crashing (and year after - I'm pretty sure - it's still crashing).

    With all not-so-good-things coming with go you are not getting anything unique or just properly implemented to compensate for them. Nothing. I have no idea why people still use go and prefer to think they are just stupid.

    ReplyDelete
    Replies
    1. Really? That sounds like one of times Go would shine. What caused the crashes?

      Delete
    2. dont blame the language for your bugs, because golang its just a tool.
      I tried to migrate from ruby, but it nearly "impossible" because the lack of productivity.

      Delete
    3. Whoever programmed such as service in Go, and got it to crash on a daily basis, is such a bad programmer they deserve an award.

      Delete
  20. Wonder if you forgot about the TLS implementation, the Go folks have a wonderful implementation of TLS 1.2 which is obviously WAYY better than the OpenSSL version which is too over used and has too many eyes looking into it for really big and succesful projects :)

    ReplyDelete
    Replies
    1. You mean the same OpenSSL that is responsible for Heartbleed and Poodle because only 2 guys were working on it and the code was was rarely looked at by anyone else?

      Delete
  21. A sarcastic criticism of the language orthogonality and lack of look ahead in Compiler.

    He wants all the syntax flexibility of C++ with all the compilation complexity of C++...

    ReplyDelete
    Replies
    1. For the record, neither "?:", nor function overloading significantly increases the complexity of the compiler or runtime, and certainly has absolutely nothing to do with parser lookahead.

      Generics are marginally harder, but given the myriad existing implementations (C++, D, Java, C#, Free Pascal) they are certainly not an unsurmountable problem, given the enormous benefits they bring.

      Delete
  22. function overload affects a _lot_ the dispatch system - it is not trivial. Ternary operator also brings problems with associativity (and memory allocation caused by r-terms during association) - because they are attached also to assignment, while if-tokens are not.

    Generics are marginally harder, true - but they come to a price. Have you seen this? http://research.swtch.com/generic

    The Go team has not ruled out generics - but they are still thinking on how to win over this conundrum. Maybe the Go community will need to take over this problem.

    From http://golang.org/doc/faq#generics:
    > Generics may well be added at some point. We don't feel an urgency for them, although we understand some programmers do.
    > Generics are convenient but they come at a cost in complexity in the type system and run-time. We haven't yet found a design that gives value proportionate to the complexity, although we continue to think about it.

    Package dependency is another problem, Go team decided to not attack yet - not because they think the current one is right, but because they can't figure out good alternatives. The community kind solved the gap with gopkg.in

    The more importantly, the sarcastic tone of the article is playing with the concept that Go was created to solve big problems only; while Go was actually created to solve a long-time compilation problem, and the most important of all - they decided to resume from where C started, no C++ - so all these C++ comparisons are moot, at least.

    ReplyDelete
    Replies
    1. I am sorry, but you are way off. Don't throw around meaningless terms like "dispatch system" and "associativity" for effect :-)

      Function overloads are resolved entirely at compile time; in layman terms on can think of them as augmenting the function name. In a statically typed language the types are, after all, available. Go *already* does that when resolving methods. The type reflection system has to be extended to support this of course, but that is not a huge hurdle.

      The ternary operator is trivial to parse as well as compile. There is no such thing as "memory allocation caused by r-terms during association - that is nonsense. Perhaps you are referring to the trouble some people have when *using" it, but that is beside the point.

      In other words, the omission of these features from the language was absolutely not driven by technical reasons, no matter what people like to pretend. They were deliberate stylistic choices based on the assumption that developers are easily confused morons.

      Delete
    2. Ternary operators trigger a memory allocation of the space of the right term before actually evaluating. Simple as that. Otherwise, makes no sense in having Ternary operators for comparison and attribution.

      If-else triggers no memory allocation unless the runtime touches an allocation within the body.

      So it was not just a stylistic choice. Attribution also means type inference in Go, and you cannot skip types like you skip them in C. So if you happen to have a Ternary operator with mixed types, besides being a typechecker error, it is also something that takes away the ability to reason about the type when the types are not visually explicit.

      If blocks force you to put these attributions in the body of the block, and the type check is profoundly simplified this way. Because you are testing (and deriving the types for test) against binary operators (one left and one right), instead of Ternary operators (one left, one right and one rightmost).

      So I really would like to see an implementation of yours of a comparison Ternary operator that proves its triviality.

      Delete
    3. This is simply not true. There is no such thing as "memory allocation for the space of the right term before actually evaluating".

      A ternary operator is syntactic sugar. It can be converted mechanically to its "if-else" form. Take this expression: "a = b*3 + (cond ? c+1:c-1)". It can be written (much more verbosely, but mechanically) as:

      t1 := b * 3
      var t2: ...
      if cond {
      t2 = c + 1
      } else {
      t2 = c - 1
      }
      a = t1 + t2

      Please demonstrate where this mysterious "space for the right term" is and also how you avoid it without the ternary operation.

      I am not even going to address the rest of your comment, "anonymous".

      Delete
  23. I always wondered how it comes that you get 3 Go experts (all of them at least Ex-Googlers, of course) to discuss about how to write some piece of Go code can end up with 3 best solutions, while at the same time the 2 of them are always crappy. It just depends on which one of the experts you ask. After you picked one solution, based on a lengthy academic discussion, you'll finally will find out that the one finally picked solution is crap as well, has some serious bugs or lack some important aspect. There's no other language that I know of where this happens repeatedly, and yes, almost predictable.

    ReplyDelete
  24. OP, seriously, you need a pussy! Or maybe call that Joyent guy for a beer.

    ReplyDelete
    Replies
    1. Anonymous, thank you for your insightful comment. I assume that intellectual pursuits and general lack of physical exercise have brought you to a point where you never "need a pussy", settling for a burger instead. The rest of us are not as enlightened...

      Delete
  25. Some very valid criticism there. Go is a disgusting language and could be made better. It's based on C after all. It's almost as ugly as Java :trollface:
    I think you're saying that swiss knife is prettier than a hammer though.
    C++ is a swiss knife that takes ages to make good use of, C# is a swiss knife that takes ages to do the job after you quickly figured out how to make use of it. Go is a hammer. It's not particularly well suited for much, but if you have a highly concurrent micro service or similar it's brilliant. It can build/run tests/deploy/reload/be serving requests in 5 seconds, and it can run 100000 concurrent users on a single machine, it's ok - I'll live without ternary operators.
    So yeah, it just might be because you're too small ;)

    ReplyDelete
    Replies
    1. Go doesn't allow me to express abstractions. Even C does better in that regard.

      Is Scheme a hammer or a Swiss army knight, for example? That would be my preference in an ideal world. It is a very simple language, yet allowing infinitely complex abstractions to be built on top of it using elegant and consistent rules.

      Delete
    2. F*ck your leaky abstractions.

      Delete
    3. Exactly, fuck abstractions (leaky or not), let us drown that ugly corpse of intent in the wonderful cement block of boilerplate.

      Delete
  26. I guess essentially what I'm saying is what you are mocking in your post :) You're not solving the kind of problems Go is build for. I'll try to give an example. Go is built as a platform for solving quite narrow and specific set of problems. Go is a systems language. I'd think that's where your frustration comes from, your typical problem must be very different from that of Go authors.
    Check this out: https://talks.golang.org/2013/oscon-dl.slide#1
    Now say in case of dl.google.com what you want is it to be fast (so you use less hardware and save lots of money), stable, handle lots of users at once well, handle lots of long running, potentially timing out processes, and not crap up and explode when suddenly load on servers increases. Abstractions add little value in that kind of system. So do virtual functions and other things you mention. Writing few more lines of code is not an issue at all compared to solving problems I mentioned.
    It's not entirely true about abstractions, you have interfaces you can cast, which you don't have in C, how is C better with abstractions? Scheme has completely different purpose to Go, I didn't measure, but I'd expect it to be far slower and consume a lot more memory. If you're doing say a CRUD web app with 10 concurrent users with lots of business logic well it's just not what Go is built for and all your criticism is true. Also I'm not saying Go as language cannot be made better, it's just that the language is not a big pain point for the kind of problems it's meant to solve.

    ReplyDelete
    Replies
    1. You have to differentiate between language and runtime and understand why Go is considered that good for certain problems. It is not because it is such a great language or because it is "magically" faster than other languages.

      Go has an excellent runtime implementing very cheap green threads. That enables synchronous IO interfaces which are much easier to use than asynchronous ones. That is it. The only thing that Go does well - simplify a certain part of coding.

      But there are other parts of coding that can (and should) be simplified too, which have been ignored by Go's designers.

      For contrast we can look have at NodeJS, which exploits the same inherent efficiencies of concurrent IO, but with a much harder to use asynchronous interfaces.

      Fortunately JavaScript as a language, ugly and disgusting as it is, is more powerful and expressive than Go, so a solution has eventually appeared, allowing synchronous coding in NodeJS without paying the cost (using generators and promises).

      Delete
    2. C'mon now, Rytis Bieliunas' comments above are fair and pragmatic. Give the language credit where due and recognize that expressiveness is a double edged sword.

      You're of course right that JS is more expressive than Go and that expressiveness has a cost ... just ask it's main advocate, Mr. Crockford. By his lights JS should be far *less* expressive.

      If expressiveness is your only (or main) criteria for judging a language, you might really like a language called Perl. Long live Perl 6!

      Delete
    3. His comment is all right, he is entitled to his opinion. However Rytis didn't reallt substantiate his opinion - why specifically is Go good? I agree that practically speaking it can be used to do the job, but an advanced programmer would not enjoy using it. Perhaps that doesn't matter in a business sense, but I still like to find enjoyment in what I do...

      Delete
  27. Whole article a sarcasm.

    ReplyDelete
  28. Go is just designed after a different style of programming. To be more precise, it is suitable for programmers who like C-style coding, not any of the languages you mentioned. And i think it is understandable, as Rob Pike is one of the designers of Go.
    I like it a lot because it gives me the simplicity of C but solves many of its problems, for example utf8 strings and working with strings as overall, build-in threads, built-in web server, distribution of binaries in unix environment(dependency hell of shared libs), and many many more.
    I have the following rule when programming: never write function outside of object and the rest - always split objects into entities(data objects w/ properties, w/o methods) and stateless services(only methods, properties only if they are instances of dependent services). For the last few years, i have programmed everything like this and i have always been able to test my functions and i never needed function overloading and virtual functions.
    Collections - there is http://golang.org/pkg/container/ but still, maps and arrays are too verbose and often get annoying.
    Some more:
    Exceptions are a matter of handling errors, in C you dont have them, you return the status of the function and 0 means success.
    defer keyword is a genius invention.

    ReplyDelete
    Replies
    1. Pray tell, how does Go solve the problem of "dependency hell of shared libs"???? Is it perhaps by the miracle of static linking!?! Truly an amazing breakthrough.

      Delete
    2. I agree it is not anything new, just done conveniently, find all the libs you need for c and write Makefile to link statically to all of them.
      I bet they are available for your system as dynamic libs but just some of them come with pre-build static version. Now you need to compile the dependencies by yourself.
      Nothing new, but in golang its just go build.

      Anyways, dependencies remind me about Go pulling always from master- I agree that this is totally insane. I use http://labix.org/gopkg.in for every import.

      Delete
  29. Bad workers always blame their tools XD

    ReplyDelete
    Replies
    1. Good workers make sure they're using the best tool for the job, therefore never have to blame the tool.

      Delete
  30. 'Go' goings to be Master of ALL and JACK of ONE.

    ReplyDelete
  31. Go is designed to solve the problem at hand.
    Abstractions are nice, but as the name implies, they are "abstractions". I can abstract a code to a beautiful concept and that won't make a hell of a sense to you, because we THINK differently. Your approach could be way better than mine, but then you'll end up reimplementing everywhere where my abstractions once were.

    In other words, Go code speaks for itself. You spend time reading about the code at hand, not trying to figure out programmer's abstractions. Go was built for coding a project with tons of developers, of different skills.
    Are abstractions nice? Of course. Do I miss them in Go? Of course. But Go is built for getting shit done, fast, concise, simple. If the language doesn't suit you, fine, don't use it. But as it seems, you aren't capable to distinguish the right tool for the right job.

    ReplyDelete
  32. Dammit! Is it me or are we going retro-volution? Are we going back? Is it a natural tendency of programmers protecting their jobs? Complicating everything?

    ReplyDelete
  33. my pet peeve with go is related to yours:

    How they can do some stuff and then not allow the dev to use the same abstraction.

    Example:
    maps can have a multiple return value or only one. But you can't do the same with your functions, that design must be too big for my little mind.
    At first I thought it was cool as I had only seen that in Common Lisp, I was soon disappointed as not to repeat that pattern as it is not golang-idiomatic

    ReplyDelete
  34. The author of the article here makes some very valid criticisms. I hope he writes more in the future. I have been programming for about 25 years now -- Go is neat, but I do see a few major glaring problems with Go that I wish people would address more candidly (without getting so emotionally worked up about it).

    1. Go lacks interactive IDE debugger support. And GDB support sucks. Neither are a priority for the authors. Call me old fashioned, but this is insane.

    It seems many Go programmers view the lack of solid IDE/debug support and integration as a net benefit (SuBLiMe TeXT , yO!). Or Printf! (Are these people serious or trolling?)

    In reality, this is a huge deficiency that needs to be addressed. I would never recommend Go for an enterprise application until this support was mature, let alone available.

    I've written Go using Idea using the Golang plugin, but even the latest support (within the past few weeks) with Delve support yields very poor results, though still better than GDB.

    At present, anything beyond the simplest data structures in Go are unreadable. Similar problem even with latest version of GDB (7.10) w/ Go 1.5. Why is this not a priority?

    And the Idea plugin and Delve are written by really smart capable people, who've been working very hard to add these features (IDE + Debugger). Why are such important efforts not supported and enabled by the language authors?

    2. The fact that we must 'vendor' dependencies in Go because of a lack of solid packaging support with the ability to specify versions ... ie. The Diamond import problem.

    The Diamond import problem is easily avoided in Python or Ruby. The fact that Go has still not addressed this after a number of years is insane. Either the authors don't care or they made a mistake in the Go 1 specification, and don't know how to fix it.

    I've read the thread w/ the creators from a couple of years ago in it's entirely. There were tons of good ideas from the Go community and they were all disregarded by the hipster-ass Go authors.

    Simply compare the status of packaging in Go with that of Python. Python has far superior package support here, especially in the last couple of years as it's become quite mature.

    3. Treating programmers like idiots.
    This may be true or necessary -- intelligence and talent is not uniformly distributed, as politically incorrect as that might be. But let's call a spade a spade -- many of the design decisions in Go are not strictly necessary on an engineering level, and are perhaps targeted towards lowest common denominator abilities, and have more of a basis in personal preference and project management than they do in computer science.

    That's fine -- if you write a language, you decide what goes in it and how it's done. But let's not pretend Go's lack of support for the ternary operator is supported by the empiric research of some Ph.D thesis. It's not.

    And I loved that quote above from the bullshitter defending Go... I think representative the frothing-at-the-mouth Go fanboys. The fact the guy defended the exclusion of the ternary operator from Go as due to problems from "memory allocation caused by r-terms during association". Pure nonsense, but hilarious nonetheless. Who hires these idiots? I sure as hell don't.

    A perfect example here of how opinionated languages can fail is another example from Google -- just look at Angular.

    In any case, Go is fine, it's got some great benefits -- I'm sold on the argument for cheap concurrency, given the trend towards massively parallel systems. That's a very specific paradigm though. And the legions of Go fan boys , including the almost fanatical adherence to it's philosophy is a bit disturbing. Jesus Christ did not return to Earth as a computer language , people.

    Nonetheless, I think Go will continue to gain adoption. Reality follows the hype. Maybe common sense will follow closely behind.

    ReplyDelete
    Replies
    1. "1. Go lacks interactive IDE debugger support" "Or Printf! (Are these people serious or trolling?)"

      http://www.linuxtoday.com/infrastructure/2000090700221OSCYKN

      "2. The fact that we must 'vendor' dependencies"

      https://docs.google.com/document/d/1Bz5-UB7g2uPBdOx-rw5t9MxJwkfpx90cqG9AFL0JAYo/edit#

      "3. Treating programmers like idiots"

      It's more about avoiding lack of productivity by avoiding too complex concepts where the amount of debate induced exceeds the time to solve the problem with simpler conceptual tools, even if it implies more code:
      - https://golang.org/doc/faq#inheritance: "Because there are no explicit relationships between types and interfaces, there is no type hierarchy to manage or discuss"
      - https://golang.org/doc/faq#overloading: "Experience with other languages told us that having a variety of methods with the same name but different signatures was occasionally useful but that it could also be confusing and fragile in practice" "Regarding operator overloading, it seems more a convenience than an absolute requirement. Again, things are simpler without it."

      They maintain a balance between open vs protect:
      https://golang.org/doc/faq#language_changes

      And you can still fork. And it's much more respective to detractors than saying "fanatical adherence" and "Maybe common sense will follow".

      Delete
  35. Long live imperative, bug ridden, verbose, ugly, retro, RY (who needs DRY) and condescending golang. I am waiting for Swift to take off. My first impressions with go were that it sucked. My first impressions with Swift are it rocked. I've moved on from Go sometime back. Not coming back. My thoughts are well resonated in this article. I have a few more to add - "comments in code overloaded with language semantics". Great. That was the last nail in the go coffin for me. I'd bet the big brains didn't design it. Kiddies must have. It is such a horrible language.

    ReplyDelete
  36. This blog awesome and i learn a lot about programming from here.The best thing about this blog is that you doing from beginning to experts level.

    Love from

    ReplyDelete
  37. I have a feeling Go is designed as it is to make it good for some kind of automatic code generation . If the runtime is fast enough and language syntax is simple enough - generator will not care about "verboseness" or abstracts .

    ReplyDelete
  38. As far as the first example is concerned: fmt.Print( math.Max(b(), c()) ) is enough. Amusing post, but as an opening example, it's a rather silly one. Start with the ternary stuff

    ReplyDelete