Hacker News new | ask | show | jobs
by klysm 844 days ago
I think boneheaded is a good way to describe the evolution of go. It seems like the original authors were convinced most of the complexity of modern languages was unjustified and have slowly proven themselves incorrect over the years
3 comments

Not a great take. The go team made a lot of decisions that weren't mainstream at the time, and nailed them. Fast builds, native binaries, language simplicity, new concurrent primitives, interface model, defer, no build flags, package system.

Yeah it has evolved a bit since, but keeping the language simple is a worthwhile goal, so they didn't make rapid changes. It was intentional and thoughtful. If you want lots of language features, pick another language. I'll take my simple one.

Also: go enums do suck.

> new concurrent primitives

You could make a case that concurrency primitives weren't mainstream in programming languages at the time. But there's not a strong case for saying that Go introduced new concurrency primitives unless you just ignore the history of programming and programming languages. Nothing in Go's concurrency model was new. Not quite mainstream, sure. But not new. [EDIT: By primitives I take you to mean built-in to the language, not brought in via libraries like pthreads or something.]

I'd also question the statement that "native binaries" were not mainstream. That seems to ignore a lot of code out there, including the C++ code that Go was (in part) meant to replace at Google.

Defer as syntax is maybe new? But some form of finally construct was in a lot of languages used at the time Go was developed. Defer flattens the code by reducing indentation levels, but it introduced nothing new in terms of concepts that weren't already being used by programmers of mainstream languages.

Faiiir. Nothing was net new concept. But the package they made was quite unique. Garbage collected but always native. No thread access, native channels and coroutines instead. Defer is pretty much net new in language design terms. No while loop?!? “If err != nil”!!? Lots of bold ideas, in a good package, and it worked so well. Calling the evolution boneheaded dismisses how hard it is to make so many opinionated bets in one go, and still make something successful.
Just pointing out that it was not really as novel as you seem to believe it was at the time it came out.

> Garbage collected but always native.

Ok, sure. There were no other native garbage collected languages. Ignoring history, this is true.

> No thread access, native channels and coroutines instead.

If we ignore history again, also new with Go.

> Defer is pretty much net new in language design terms.

I can't think of an equivalent in the form of syntax, so sure. This is a point to Go. It's a small change, but useful for flattening code.

> No while loop?!?

I don't know why the exclamation mark. They have one named type of loop with `for`, but they definitely have a while loop:

  for x <= 10 {
    ...
  }
That's a while loop, it's not an infinite loop, it's not a do-while loop. That they reduced their looping constructs to one name (and then determine which actual loop kind by what's between `for` and `{`) does not mean they actually removed while loops. This does simplify the syntax, maybe.

> “If err != nil”!!?

[edit: missed this one]

  if (some_c_lib_fun(...) == -1) {
    // check the errno
  }
> Calling the evolution boneheaded

I didn't. Why are you putting this here?

defer is a poor man’s C# IDisposable (or even IAsyncDisposable)

    // The file handle will be freed at OS level when exiting current scope
    using var file = File.OpenHandle("somefile");
defer is best compared to try/finally or unwind-protect and friends. You can defer any action, not just whatever the IDisposable happens to cleanup. It also gets access to the lexical scope for its deferred actions.

You could imitate that with IDisposable, but it would be overkill compared to just using finally (in C#).

^ thread
I totally agree that go nailed the head on a lot of things, including the list you provided (minus package system). I’m not convinced the evolution was intentional though from the start. From my memory the _attitude_ of the go ecosystem was that generics were not worth the complexity (for example). I don’t have any concrete evidence of that, it’s just the vibe I got from talking to folks about it.

I also have great distaste for error handling in go but that’s a distinct argument to have.

>>It seems like the original authors were convinced most of the complexity of modern languages was unjustified and have slowly proven themselves incorrect over the years

Python was the same way a few years back. People would give elaborate lectures on why Perl's features were so bad, only that they agreed to add many such features to Python within a decade, even at the extreme act of breaking backwards compatibility.

This is seems to be a common arc to so many things. When you start you are all about principles and as you age, you realise practicalities of every day life demand making lots of tradeoffs and deviations from founding principles.

> convinced most of the complexity of modern languages was unjustified

You don't think that most of the complexity of modern languages is unjustified?

I think most modern languages have complexity in the wrong areas. The type systems are not complex enough to capture the things I want algebraic data types with exhaustiveness guarantees).