thomashabets2 8 days ago

Unlike the author, I would actually say that Go is bad. This article illustrates my frustration with Go very well, on a meta level.

Go's design consistently at every turn chose the simplest (one might say "dumbest", but I don't mean it entirely derogatory) way to do something. It was the simplest most obvious choice made by a very competent engineer. But it was entirely made in isolation, not by a language design expert.

Go designs did not actually go out and research language design. It just went with the gut feel of the designers.

But that's just it, those rules are there for a reason. It's like the rules of airplane design: Every single rule was written in blood. You toss those rules out (or don't even research them) at your own, and your user's, peril.

Go's design reminds me of Brexit, and the famous "The people of this country have had enough of experts". And like with Brexit, it's easy to give a lame catch phrase, which seems convincing and makes people go "well what's the problem with that, keeping it simple?".

Explaining just what the problem is with this "design by catchphrase" is illustrated by the article. It needs ~100 paragraphs (a quick error prone scan was 86 plus sample code) to explain just why these choices leads to a darkened room with rakes sprinkled all over it.

And this article is just about Go channels!

Go could get a 100 articles like this written about it, covering various aspects of its design. They all have the same root cause: Go's designers had enough of experts, and it takes longer to explain why something leads to bad outcomes, than to just show the catchphrase level "look at the happy path. Look at it!".

I dislike Java more than I dislike Go. But at least Java was designed, and doesn't have this particular meta-problem. When Go was made we knew better than to design languages this way.

5
kbolino 8 days ago

Go's designers were experts. They had extensive experience building programming languages and operating systems.

But they were working in a bit of a vacuum. Not only were they mostly addressing the internal needs of Google, which is a write-only shop as far as the rest of the software industry is concerned, they also didn't have broad experience across many languages, and instead had deep experience with a few languages.

emtel 8 days ago

Rob Pike was definitely not a PL expert and I don’t think he would claim to be. You can read his often-posted critique of C++ here: https://commandcenter.blogspot.com/2012/06/less-is-exponenti...

In it, he seems to believe that the primary use of types in programming languages is to build hierarchies. He seems totally unfamiliar with ideas behind ML or haskell.

kbolino 8 days ago

Rob Pike is not a PL theoretician, but that doesn't make him not an expert in creating programming languages.

Go was the third language he played a major part in creating (predecessors are Newsqueak and Limbo), and his pedigree before Google includes extensive experience on Unix at Bell Labs. He didn't create C but he worked directly with the people who did and he likely knows it in and out. So I stand by my "deep, not broad" observation.

Ken Thompson requires no introduction, though I don't think he was involved much beyond Go's internal development. Robert Griesemer is a little more obscure, but Go wasn't his first language either.

thomashabets2 7 days ago

Re-reading Pike's C++ critique now, I do chuckle at things like;

> Did the C++ committee really believe that was wrong with C++ was that it didn't have enough features?

C++ was basically saved by C++11. When written in 2012 it may have been seen as a reasonable though contrarian reaction, but history does not agree. It's just wrong.

I'm very much NOT saying that every decision Go made was wrong. And often experts don't predict the future very well. But I do think that this gives further proof that while not a bad coder by any means, no Pike is very much not an expert in PL. Implementing ideas you had from the 1980s adding things you've learned since is not the same thing as learning lessons from the industry in that subfield.

kbolino 7 days ago

I would actually say even in 2012 the observation was probably wrong already, but notably Pike actually made it in the mid-aughts and was simply relaying it in 2012. However, being wrong about what was good for the future of C++ isn't really here nor there; Thompson also famously disliked C++. Designing a language that intentionally isn't like C++ does not equate to me as a rejection of expertise.

elzbardico 8 days ago

My point of view is that Rob Pike is a brilliant engineer, but a little too much opinionated for my tastes.

thomashabets2 8 days ago

I guess we're going into the definition of the word "expert".

I don't think the word encompasses "have done it several times before, but has not actually even looked at the state of the art".

If you're a good enough engineer, you can build anything you want. That doesn't make you an expert.

I have built many websites. I'm not a web site building expert. Not even remotely.

kbolino 8 days ago

I think both C and Go (the former is relevant due to Thompson's involvement in both and the massive influence it had on Go) are very "practical" languages, with strict goals in mind, and which delivered on those goals very well. They also couldn't have existed without battle-tested prior experience, including B for C and Limbo for Go.

I also think it's only from the perspective of a select few, plus some purists, that the authors of Go can be considered anything other than experts. That they made some mistakes, including some borne of hubris, doesn't really diminish their expertise to me.

thomashabets2 8 days ago

But my point is that articles like this show how that if you don't keep up with the state of the art, you run the risk of making this predictable mistakes.

If Go had been designed in the 1980s then it would have been genius. But now we know better. Expertise is more than knowing state of the art as of 30 years prior.

kbolino 7 days ago

I don't think the state of the art ca. 2007 was the same as it seems today.

For one thing, Go took a number of forward-thinking stances (or ones which were, at least, somewhat unusual for its time and target audience), like UTF-8 strings (granted, Thompson and Pike created the encoding in the first place), fat pointers for strings and slices, green threads with CSP (though channels proved to be less useful than envisioned) and no function coloring, first-class functions, a batteries-included standard library, etc.

The only things I can think of which Go did that seemed blatantly wrong in that era would be the lack of generics and proper enums. Null safety, which IMO proved to be the killer development of that era, was not clearly formed in industry yet. Tony Hoare hadn't even given his famous "billion-dollar mistake" talk yet, though I'm sure some idea of the problem already existed (and he did give it in 2009, a couple of years into Go's development but also before its first public release). I know others find the type system lacking, but I don't think diving hard into types is obviously the best way to go for every language.

If one were to seriously investigate whether expertise was valued by Pike et al., I think it would start by looking at Erlang/OTP. In my opinion, that ecosystem offers the strongest competition against Go on Go's own strengths, and it predates Go by many years. Were the Go designers aware of it at all? Did they evaluate its approach, and if so, did they decide against it for considered reasons? Arguing against C++ was easy coming from their desired goals, but what about a stronger opponent?

9rx 7 days ago

> The only things I can think of which Go did that seemed blatantly wrong in that era would be the lack of generics and proper enums.

Typescript added "improper" enums several years later. Which is especially interesting as it is the one feature in Typescript that doesn't map directly to Javascript. I'm not sure even that one was the settled science back then.

Generics were well established at that time, but that one didn't escape the Go authors. From day one it was explicitly called out as a feature Go should have, but that they hadn't figured out how to integrate it. https://youtu.be/rKnDgT73v8s?t=3257 Despite Taylor's admirably insistent efforts to find a solution (with 8+ proposals to his name, dating back to before Go was released to the public!), it ultimately required convincing an outside expert to lend a hand.

> I know others find the type system lacking

It may be lacking by today's standards where types are all the rage, but at the time we should also remember that it was the case that types simply weren't cool. People had grown tired of "doing XML sit-ups" and had fully embraced dynamic languages in reaction to that. Go was built in that time, for that time, explicitly intending to be a language that felt like a dynamic language but with the performance advantages of a static language. https://youtu.be/rKnDgT73v8s?t=471

0x696C6961 8 days ago

The Brexit comparison doesn't hold water — Brexit is widely viewed as a failure, yet Go continues to gain popularity year after year. If Go were truly as bad as described, developers wouldn't consistently return to it for new projects, but clearly, they do. Its simplicity isn't a rejection of expertise; it's a practical choice that's proven itself effective in real-world scenarios.

tl 8 days ago

This is optics versus reality. Its goal was to address shortcomings in C++ and Java. It has replaced neither at Google and its own creators were surprised it competed with python, mostly on the value of having an easier build and deploy process.

lelanthran 7 days ago

If we're using "did not meet the stated goal" as a bar for success, then Java also "failed", because it was developed as an embedded systems language and only pivoted to enterprise applications after being a dismal and abject failure at the stated goal.

If Java is not a failure then neither is Go.

If Go is a failure then so is Java.

Personally I think it is inaccurate to judge a mainstream, popular and widely adopted language as a failure just because it did not meet the goal set at the initiation of the project, prior to even the first line of code getting written.

0x696C6961 8 days ago

Go has replaced Java and C++ in numerous other environments.

cyberpunk 8 days ago

We use a boatload of off the shelf go components; but i don't see it making any progress at replacing java at my bank. We are extremely happy with where java is these days...

pdimitar 6 days ago

Really bad example if you ask me. Banks are literally the last institutions that will make a change.

dilyevsky 8 days ago

> It has replaced neither

Except that it did. Just because people aren’t rewriting borg and spanner in go doesn’t mean it isnt default choice for many of infra projects. And python got completely superseded by go even during my tenure

Joker_vD 7 days ago

And haven't people actually rewritten Kubernetes in Go? I vaguely recall it was originally written in Java.

thomashabets2 8 days ago

I would say this is another thing that would take quite a while to flesh out. Not only is it hard to have this conversation in text-only on hackernews, but HN will also rate limit replies, so a conversation once started cannot continue here to actually allow the discussion participants to come to an understanding of what the they all mean. Discussion will just stop once HN tells a poster "you're posting too often".

Hopefully saving this comment will work.

Go, unlike Brexit, has pivoted to become the solution to something other than its stated target. So sure, Go is not a failure. It was intended to be a systems language to replace C++, but has instead pivoted to be a "cloud language", or a replacement for Python. I would say that it's been a failure as a systems language. Especially if one tries to create something portable.

I do think that its simplicity is the rejection of the idea that there are experts out there, and/or their relevance. It's not decisions based on knowledge and rejection, but of ignorance and "scoping out" of hard problems.

Another long article could be written about the clearly not thought through use of nil pointers, especially typed vs untyped nil pointers (if that's even the term) once nil pointers (poorly) interact with interfaces.

But no, I'm not comparing the outcome of Go with Brexit. Go pivoting away from its stated goals are not the same thing as Brexiteers claiming a win from being treated better than the EU in the recent tariffs. But I do stand by my point that the decision process seems similarly expert hostile.

Go is clearly a success. It's just such a depressingly sad lost opportunity, too.

9rx 7 days ago

> It was intended to be a systems language to replace C++

More specifically, it was intended to replace the systems that Google wrote in C++ (read: servers). Early on, the Go team expressed happy surprise that people found utility in the language outside of that niche.

> but has instead pivoted to be a "cloud language"

I'm not sure that is really a pivot. At the heart of all the "cloud" tools it is known for is a HTTP server which serves as the basis of the control protocol, among other things. Presumably Go was chosen exactly because of it being designed for building servers. Maybe someone thought there would be more CRUD servers written in it too, but these "cloud" tools are ultimately in the same vein, not an entirely different direction.

> or a replacement for Python

I don't think you'd normally choose Go to train your ML/AI model. It has really only gunned for Python in the server realm; the very thing it was intended to be for. What was surprising to those living in an insular bubble at Google was that the rest of the world wrote their servers in Python and Ruby rather than C++ like Google – so it being picked up by the Python and Ruby crowd was unexpected to them – but not to anyone else.

pdimitar 6 days ago

> I don't think you'd normally choose Go to train your ML/AI model. It has really only gunned for Python in the server realm

I don't think anyone ever claimed Golang will displace Python in the ML area. But in a world where Golang and Elixir exist (two languages with stacks that make starting a new web / API projects extremely easy, almost trivial), not to mention old-timers like Ruby, the amount of people reaching for Python for web / API projects is depressingly high. "Sunk cost fallacy", "one-trick pony", "Stockholm syndrome" and a few others come to mind when thinking about the programmers doing it.

0x696C6961 8 days ago

> I do think that its simplicity is the rejection of the idea that there are experts out there, and/or their relevance. It's not decisions based on knowledge and rejection, but of ignorance and "scoping out" of hard problems.

Ok, I'll ask the obvious question. Who are these experts and what languages have they designed?

> Another long article could be written about the clearly not thought through use of nil pointers, especially typed vs untyped nil pointers (if that's even the term) once nil pointers (poorly) interact with interfaces.

You're getting worked up about something that's hardly ever an issue in practice. I suspect that most of your criticisms are similar.

kbolino 7 days ago

I think there's two layers to the typed vs. untyped nil issue (which is really about nil pointers in an interface value vs. the zero value of interface types).

The first is simple confusion, such as trying to handle "all nils" the same way. This is not necessary, though I have seen some developers coming from other languages get hung up on it. In my experience, the only real use for "typed nil" is reflection, and if you're using reflection, you should already know the language in and out.

However, the other aspect is that methods with pointer receivers on concrete types can have default behavior when the receiver is nil, while interfaces cannot. In the expression foo.Bar(), you can avoid a panic if foo is *T, but when foo is an interface, there is no way around the panic without checking foo's value explicitly first. Since nil is the default value of all interface types, even if you create a dummy/no-op implementation of the interface, you still risk nil panics. You can mitigate but never truly remove this risk.

nvarsj 8 days ago

The creators thought that having 50% of your codebase be `if (err != nil) { ... }` was a good idea. And that channels somehow make sense in a world without pattern matching or generics. So yeah, it's a bizarrely idiosyncratic language - albeit with moments of brilliance (like structural typing).

I actually think Java is the better PL, but the worse runtime (in what world are 10s GC pauses ever acceptable). Java has an amazing standard library as well - Golang doesn't even have many basic data structures implemented. And the ones it does, like heap, are absolutely awful to use.

I really just view Golang nowadays as a nicer C with garbage collection, useful for building self contained portable binaries.

cempaka 7 days ago

> I actually think Java is the better PL, but the worse runtime (in what world are 10s GC pauses ever acceptable).

This seems like a very odd/outdated criticism. 10s CMS full STW GCs are a thing of the past. There are low-latency GCs available for free in OpenJDK now with sub-millisecond pause times. Where I've seen the two runtimes compared (e.g. Coinbase used both langs in latency-sensitive exchange components) Java's has generally come out ahead.

nvarsj 6 days ago

Yes, probably out of date. Memory management was always the JVMs Achilles heel (either long pause times or too much memory usage). If that’s fixed in recent JDKs, awesome.

thomashabets2 7 days ago

I think Java made many decisions that turned out to be bad only in retrospect. In Go we knew (well, experts knew) already that the choices were bad.

Java is a child of the 90s. My full rant at https://blog.habets.se/2022/08/Java-a-fractal-of-bad-experim... :-)

Mawr 8 days ago

Your post is pure hot air. It would be helpful if you could provide concrete examples of aspects of Go that you consider badly designed and why.

int_19h 7 days ago

The intersection of nil and interfaces is basically one giant counter-intuitive footgun.

Or how append() sometimes returns a new slice and sometimes it doesn't (so if you forget to assign the result, sometimes it works and sometimes it doesn't). Which is understandable if you think about it in terms of low-level primitives, but in Go this somehow became the standard way of managing a high-level list of items.

Or that whole iota thing.

9rx 7 days ago

> Or that whole iota thing.

What is the whole iota thing?

For what it is, the iota design is really good. Languages like C and Typescript having having the exact same feature hidden in some weird special syntax look silly in comparison, not to mention that the weird syntax obscures what is happening. What Go has is much more clear to read and understand (which is why it gets so much grief where other languages with the same feature don't – there is no misunderstandings about what it is).

But maybe you are implying that no language should present raw enums, rather they should be hidden behind sum types? That is not an unreasonable take, but that is not a design flaw. That is a different direction. If this is what you are thinking, it doesn't fit alongside the other two which could be more intuitive without completely changing what they are.

chabska 7 days ago

> Go could get a 100 articles like this written about it, covering various aspects of its design

Actually... https://100go.co/