1. 29
  1. 33

    I have worked in go for 6 years and it’s been catalytic to my career. I am the go expert at my current job. It’s a fine tool for what you need it to do; but the real problem is that too many people treat it literally like Java. There’s pointless abstractions in codebases I’ve seen. There’s patterns from other languages wholesale pulled in just because it felt nice. Kubernetes is a perfect example of Gova.

    Honestly after using Go for so long I’m learning Zig for low level and operating systems programming. Zig requires you to manage your own memory, but at this point I’m really okay with that.

    1. 8

      Gova… a good word for the code base I’m working on now :(

      1. 6

        The BourneShell was written in C using macros to make it look like some variant of ALGOL. I’ve never forgiven that guy after having a job debugging it.

        1. 5

          So true. At my current job I’ve seen “XYZBuilderFactory” stuff in Go and all kinds over over-complex constructs. I love the simplicity that Go offers and despise useless complexity more and more by each day. Software needs to be as simple as possible to be maintainable and extensible. Juding the author of this article by his text he must be my anti-hero.

        2. 26

          I think by criticising Go the author actually ended up stating some of the reasons for Go’s popularity and success.

          A developer working in Go and only Go will help his business’s bottom line, and the shareholders will be happy

          Yes, the number one reason we are employed as software engineers.

          I’ve been trying learn Rust, and I have a little server project called Monologued that I’ve been hacking on since early December. I haven’t gotten it working. I already had some major components working, and I decided to try at write Monologued in Go. It took about six hours.

          Great, job done.

          Go might not be as intellectually stimulating as some other languages, but we’re not being paid to solve puzzles for fun. We’re being paid to produce working, production software.

          1. 5

            Sometimes I’m in awe of how candid are some people when writing blog posts. You can say this having a beer with your friends, but you don’t publish something that shows how little you understand your job and your role in a company.

            That’s how I feel writing in Go. I didn’t learn anything writing in Go.

            Frankly, I hope this is not read by the next guy that decides if you join a new job. They’re not paying you for learning “about something”, they’re paying you to deliver.

            No one will ever write great software in Go.

            Because spending six hours programming a finger server gives you the insight to determine Go future.

          2. 20

            This essay feels like a form of gatekeeping: “if you don’t do this hard thing, you’re a greenhorn, amateur, or youth.”

            I dislike Go, too, but I construct my arguments around the things I value and convey those instead of quaintly summarizing my dislike as “this is a toy compared to what I prefer and value.”

            1. 27

              This person fundamentally misunderstands.


              Go is not for beginners. Go is for people who are over their infatuation with gratuitous complexity and iamverysmart programming. Go is for programmers who want to get things done, not show off. It’s a low cognitive overhead language designed to make it easy to write and ship software and otherwise get the F out of the way. The ecosystem is full projects written to do things not to show off how smart the programmer is by their clever use of language features.

              I’ve been programming for over 20 years and I love Go. It’s not perfect by any stretch and I am also eyeing Rust these days, but Go is a refreshing breath of fresh air after decades of languages like Java and C++ on the static front that encourage over-engineering and sluggish dynamic languages like Ruby, Python, and JavaScript that crumble into messes of hidden bugs when you add more than a few coders to a project. For decades the only refuge has been the 1970s experience of C or the disciplined use of C++ and Java (intentionally avoiding over-engineering).

              1. 6

                I feel like you’ve accurately hit the nail on the head and captured my sentiments exactly. I’ve settled on Go because it’s productive and it’s surprisingly easy to write something and find that it works exactly as you intended first time. It’s not perfect—no language is—but I get more done and feel fulfilled more frequently than I do frustrated with it, so I take that as a win.

                1. 2

                  I feel like if Go were for beginners it would not expose pointer internals, syscalls, unsafe, etc. It lets you go low level to the point of doing things that “are not guaranteed to work in future versions of the runtime.” It exposes its internals a ton more than e.g. Java or C#.

                  It’s clearly a language designed for high productivity by programmers who know what they’re doing. Beginners can use it of course but there are ways to shoot yourself in the foot.

                  The biggest language lawyer complaint about Go is that it lacks generics. I’ve found that I rarely miss generics and that 90% of the time I can come up with another solution that is just as fast and at least as clear.

                  Here’s a great example:


                  Binary search in Go is implemented by passing a function that can see your data. No need to implement binary search on a generic.

                  That kind of thing can be done most of the time. I’ve heard these kinds of idioms described as “Gooey” as in “the Go way.”

                  The only real area where not having generics hurts is when you’re trying to implement really deep algorithms and heavy math and get high performance across both simple types like float64 and complex structured types. This is the area where C++ shines the brightest IMHO. In that case I’d be tempted to do the math kernel in C++ and call it from Go and do the more “boring” stuff in Go which is more productive.

              2. 41

                It doesn’t encourage growth. A developer working in Go and only Go will help his business’s bottom line, and the shareholders will be happy, but he will always be a mediocre programmer which is why mediocre coders are so fond of Go.

                Saying that someone, by deciding to use a tool over other, will be forever a mediocre coder, is just wrong at so many levels, this is disgusting.

                1. 13

                  Exactly. Growth is not just about coming to grips with terrible programming languages, or with brilliant but complicated languages.

                  It comes from learning to work together with others and learning to build complicated, often interconnected, software. This has inherent complexity, both on a technical and human level.

                  You don’t need to use a terrible language to grow in those things.

                  1. 11

                    I’m reminded of the cliche, it’s a poor craftsman that blames his tools.

                    1. 2

                      The Law of the instrument, may be a relevant concept to bring up though, in conjunction with your noted cliche.

                      “I suppose it is tempting, if the only tool you have is a hammer, to treat everything as if it were a nail.”
                      – Abraham Maslow

                      That said, I do more strongly align with your stated cliche. I think we are lucky to have such a wide range of quality tools to pick from these days.

                  2. 13

                    I’m currently hiring and if I found that a candidate had written this, I would decline to interview them.

                    1. 1

                      Are you hiring remote first or in the Dallas area, by any chance?

                    2. 8

                      And that’s my problem with Go. It doesn’t encourage growth.

                      You mean the kind of growth where you end up with complicated Swift, C++ or Rust code bases? Code that nobody except the original programmer understands because it was a “personal growth” project and every trick and language feature was used?

                      No thanks. I’ve been in that situation, on the receiving end, many times the past decades. And every time it was incredibly obvious that the code should have been written in easier to understand way, more pragmatic, that does not for example require a masters in C++ Templates. Or a degree in Monad operators in Swift.

                      Personal growth is extremely important and should be encouraged at all levels in an organization. But personal growth does NOT EQUAL COMPLEXITY. Personal growth can also be all about building large scale complicated applications in Go that are there to last, that your whole team understands well, that can go into the future.

                      1. 7

                        Working in Go does not suck. The problem is that if you’re not working in something that sucks, you are not growing.

                        You can work on solving a complex problem using a language that is your ally, not another enemy, and keep growing as a developer.

                        You shouldn’t think that your tool sucks. Thinking so, should be a red alert saying “switch the tool”.

                        1. 7

                          I agree with the author that there are whole categories of things you won’t learn if you do nothing in your career but write servers in Go. However, there are plenty of things you will learn by building real software with real people, regardless of your choice of language (in fact you may learn more about that by choosing a “worse” language).

                          You should definitely learn other languages as well, and learn the right places to use them, but Go isn’t just for preschoolers. It has a legitimate niche.

                          1. 3

                            The key point here is our programmers are Googlers, they’re not researchers. They’re typically, fairly young, fresh out of school, probably learned Java, maybe learned C or C++, probably learned Python. They’re not capable of understanding a brilliant language but we want to use them to build good software. So, the language that we give them has to be easy for them to understand and easy to adopt. – Rob Pike

                            God, this quote explains so much

                            1. 2

                              And now I’d wish for something as simple and well curated for the Frontend side of programming.

                              1. 2

                                No one will ever write great software in Go.

                                Kubernetes, Docker, et cetera are a thing, no?

                                1. 6

                                  Having had the pleasure to deal with Docker, I think the author is completely on point.

                                  1. 1

                                    I’d rather use any of the other tools written in golang before calling those “great”. They are useful, but they are meant to be operated by specific types of teams and with specific concerns.

                                  2. 2

                                    Why does the author dislike ESR? Politics?

                                    1. 3

                                      That’s usually the reason.

                                      1. 1

                                        Where is the dislike of ESR expressed? There’s no hit on the page for “ESR” or “Raymond”.

                                        1. 3

                                          “mediocre coders are so fond of Go” links to an ESR blog post about not liking Rust.

                                          1. 4

                                            Thanks! I missed that.

                                            I find it amusing that the situation ESR describes in his post is the same as the one described by the post’s author - they tried to write something in Rust, tried it in Go, and it worked great.

                                            ESR: “Go is preferable to Rust”

                                            Elf: “Go is too damn easy compared to Rust”

                                            As to why people dislike ESR… you’ll have to ask the author his reasons. Personally I find him a self-publicizing blowhard. He’s a decent polemicist and author, and I think he’s done a goop job popularizing Open Source (as opposed to Free Software), but he’s probably not as good a programmer as he lets on.

                                      2. 2

                                        It’s basically pg’s ludicrous “blub language” elitism with Rust substituting for LISP.

                                        1. 2

                                          From January 2018, so borderline historical ;)

                                          In all seriousness, dismissing a language based on the first book about it you find seems a bit lazy.

                                          1. 26

                                            It’s extremely important, since there are so many languages and since they tend to be near each other in expressive power, to be able to dismiss a language without spending a deep amount of time grokking its subtle nature. If there are showstopping misfeatures in a language, then they should be recognizable from a distance. In modern programming-language theory and design, we imagine what languages might be like, had they made better choices; we recognize that sometimes a language’s best purpose is to serve as a warning to others.

                                            Any of these are showstopping misfeatures of Go, to me, and I don’t think any of them have changed much since Go was released publically:

                                            • There are some seventeen numeric types, and next-to-no generic programming technology.
                                            • Error handling is completely ad-hoc.
                                            • Unicode strings can contain invalid inner UTF-8 bytes.
                                            • NULL’able pointers.
                                            • Zero values. Also, partially-uninitialized values.
                                            • iota and no enums.
                                            • new and make.

                                            Go is patrician and sadistic in its demands of programmer self-discipline. Basic error-handling requires a social convention and a code tax that I’ve measured at anywhere from 5% to 30% by lines of code. Basic arithmetic requires repetitious entry of spurious formulae without correctness checks.

                                            The reviewer appears to have not just read a book, but also availed themselves of Go’s official documentation and some other resources; they also played with the language and wrote a small project, a finger server, using Go.

                                            1. 3

                                              I stand corrected, I missed that they had written a project using Go.

                                              1. 1

                                                17 different numeric types sounds terrible until you realizethat 11 of them are different size ints and 2 are different size floats. You need those types to do e.g. network code. That’s 13. Add 2 complex types boolean and string. A showstopper, eh? Unicode strings can contain invalid utf-8 bytes. There are no unicode strings, just strings. Right? Don’t you need that for processing arbitrary data that may contain invalid bytes?

                                                “Patrician and sadistic” is a good line, but I have no idea what you mean.


                                                What do you mean by “Basic arithmetic requires repetitious entry of spurious formulae without correctness checks.”

                                                1. 4

                                                  How many numeric types does a language need? These languages can all do “network code”:

                                                  • Racket has 80
                                                  • C99 has 28
                                                  • Go has 17 (of which four, not two, are floating-point)
                                                  • Python 3 has four: int, for integers; float, for IEEE 754 floating-point; complex, for complex pairs of floats; and bool, for Booleans
                                                  • Monte has two: Int, for integers; and Double, for IEEE 754 double-precision floating-point
                                                  • GNU Forth (gforth) has one type: the cell, a bitstring. I couldn’t find a page in their user manual which states this plainly, but I was able to locate demonstration networking code in gforth.

                                                  If a Unicode string can contain invalid bytes, then its encapsulation has failed. There’s no nice way to put it. Illegal states shouldn’t be representable. Other languages, e.g. Monte, Haskell, or Python 3, support both Unicode strings and byte strings, with different iterators returning different types of elements.

                                                  Recent examples of basic arithmetic in Go being complicated by Go’s design choices include Why no max/min function for integer in GoLang and Survey of Rounding Implementations in Go.

                                                  1. 2

                                                    Seriously? Do you understand the layout of an IP packet?

                                                    FYI: as far as I know, Go does not have unicode strings. Go has byte strings plus assists to make it easer to work with unicode embedded in byte strings. Computers have bytes. If I write a program to, for exampe, read data from a file that is supposed to be in UTF-8 format, something needs to be able to represent that data as it is and then check for UTF-8 encoding.

                                                    Not having a built in max in Go is clearly a fatal error though. Might as well give up entirely.

                                                    1. 2

                                                      From that last link

                                                      Finally, correctly rounding floating point numbers is ridiculously hard. It is no surprise that Java was broken for 6 major versions (15 years since the release of the Java 1.0 until Java 7). At least Go got there in less time than that.

                                                  2. 1

                                                    As a confirmed language nerd I totally hear what you’re saying. However, some of the things you list are not as clear-cut as they sound.

                                                    For example, while there are no user-accessible generics, there are judicious builtin generics that handle some very common cases. There are a lot of numeric types, but there are also untyped numeric constants. Error handling is ad hoc, but one can argue that’s better than just not considering errors at all, as other “safer” languages may encourage. Strings don’t have to be valid UTF-8, but that’s usually only relevant at system boundaries anyway.

                                                    I would put nil, zero values, iota, new, and make under the heading of “a more convenient C”, and you can certainly argue whether being “like C” in that way is good on balance.

                                                    As a language nerd who used to write a lot of C, I find Go weirdly pleasant when operating in its sweet spot. IMO, that spot is relatively small network service components, or simple command-line utilities.

                                                    1. 3

                                                      I find it interesting that when people with a track record of success like Rob Pike and colleagues come up with a very successful programming language, it is so easy for some people to dismiss their design decisions as stupid. Generics is nowhere near as obvious a win as often claim. The UTF-8 issue is inescapable for a language where you want to be able to read in unstructured files or packets as byte sequences which may embed some UTF-8. iota is a clever idea that is immediately useful. Error handling in go is straightforward.

                                                      1. 2

                                                        I understand your desire to apologize for Go, since you find it useful. However, I’m afraid that you are only reinforcing my point. Go’s authors made choices about which tools Go programmers can use, and the choices that they made were very limiting.

                                                        On the topic of error handling, when I say that Go has ad-hoc error handling, I am indeed saying that errors are not considered at all. As the Go wiki on errors explains, so-called error values are merely strings with an interface. Since error values are returned like normal values, with typical calling convention, there is no erroring state; there are no special syntactic tools for indicating that an error is likely, handled, present, catchable, etc.

                                                        (Out of curiosity, which “safer” languages are you thinking of? There are some languages that insist on totality, but totality is an even more restrictive condition, and total languages can still have error-handling! Indeed, in total functional languages, it is not uncommon to build error-handling monads or similar tools.)

                                                        nil is an interesting value. Many object-based languages find that a nil or null is necessary as a matter of semantics, and in mathematics, we know that terminal objects and zero objects appear in many different contexts. However, the specific combination of nil and pointers is what causes the “billion-dollar mistake”. Languages as old as C++ and Ada have had ways to indicate that a value reference should not be null, and modern object-based languages usually don’t permit nullable object references, with Java and C♯ being the most obvious exceptions. When a language like Python, Ruby, or E dereferences a reference, they always get a valid object back.

                                                        1. 1

                                                          Go’s authors made choices about which tools Go programmers can use, and the choices that they made were very limiting

                                                          Yes. That was a deliberate design choice - much as C authors decided to leave a lot to the OS/hardware and Lisp authors decided to see “everything is a list” and the authors of Prolog decided to limit programmers to problems that can be solved with a unification algorithm. Not everyone wants to develop another Perl.

                                                          The “billion dollar mistake” is a nice story, but it’s an opinion, unmoored to any data. Pointers are useful. If you have pointers, you need a terminal value. FWIW: both Rust and Haskell have null pointers, only hidden behind the door in the hopes that people will politely pretend not to notice they are there.

                                                          I understand your desire to apologize for Go, since you find it useful.

                                                          That a funny comment.

                                                  3. 1

                                                    There is something quite astonishing about watching someone take all the skill they’ve spent thousands of hours mastering only to wring lovely music out of toy pianos, plastic recorders, kindergarten bongos, and little wooden xylophones. It’s only when you step back for a moment and realize that if they sound that amazing on toys, they must be even more amazing when playing on instruments meant for adult hands.

                                                    I take away a different thing from this observation. Photographers are often told that the camera does not matter - it’s the composition and lighting, the photographer’s eye. Music isn’t about technical perfection. It’s about expression. Just as we can spot a fake smile we can spot artistic things that are technically perfect but not artistic.