Most active commenters
  • frollogaston(13)
  • rednafi(10)
  • pjmlp(5)

←back to thread

302 points Bogdanp | 65 comments | | HN request time: 1.459s | source | bottom
1. rednafi ◴[] No.44392307[source]
I’m glad that Go went the other way around: compilation speed over optimization.

For the kind of work I do — writing servers, networking, and glue code — fast compilation is absolutely paramount. At the same time, I want some type safety, but not the overly obnoxious kind that won’t let me sloppily prototype. Also, the GC helps. So I’ll gladly pay the price. Not having to deal with sigil soup is another plus point.

I guess Google’s years of experience led to the conclusion that, for software development to scale, a simple type system, GC, and wicked fast compilation speed are more important than raw runtime throughput and semantic correctness. Given the amount of networking and large - scale infrastructure software written in Go, I think they absolutely nailed it.

But of course there are places where GC can’t be tolerated or correctness matters more than development speed. But I don’t work in that arena and am quite happy with the tradeoffs that Go made.

replies(9): >>44392470 #>>44392882 #>>44393976 #>>44394789 #>>44395314 #>>44395527 #>>44395624 #>>44398142 #>>44398420 #
2. galangalalgol ◴[] No.44392470[source]
That is exactly what go was meant for and there is nothing better than picking the right tool for the job. The only foot gun I have seen people run into is parallelism with mutable shared state through channels can be subtly and exploitably wrong. I don't feel like most people use channels like that though? I use rust because that isn't the job I have. I usually have to cramb slow algorithms into slower hardware, and the problems are usually almost but not quite embarrassingly parallel.
replies(1): >>44395068 #
3. ode ◴[] No.44392882[source]
Is Go still in heavy use at Google these days?
replies(2): >>44393168 #>>44396765 #
4. hu3 ◴[] No.44393168[source]
What would they use for networking if not Go?
replies(2): >>44394634 #>>44395892 #
5. mark38848 ◴[] No.44393976[source]
What are obnoxious types? Types either represent the data correctly or not. I think you can force types to shut up the compiler in any language including Haskell, Idris, PureScript...
replies(4): >>44394280 #>>44395145 #>>44396684 #>>44408670 #
6. Mawr ◴[] No.44394280[source]
I'd say you already get like 70% of the benefit of a type system with just the basic "you can't pass an int where string is expected". Being able to define your own types based on the basic ones, like "type Email string", so it's no longer possible to pass a "string" where "Email" is expected gets you to 80%. Add Result and Optional types (or arguably just sum types if you prefer) and you're at 95%. Anything more and you're pushing into diminishing returns.
replies(1): >>44395019 #
7. surajrmal ◴[] No.44394634{3}[source]
C++ and Java. Go is still used, but it's never caught up to the big two.
replies(1): >>44398396 #
8. mike_hearn ◴[] No.44394789[source]
> fast compilation is absolutely paramount. At the same time, I want some type safety, but not the overly obnoxious kind that won’t let me sloppily prototype. Also, the GC helps

Well, that point in the design space was already occupied by Java which also has extremely fast builds. Go exists primarily because the designers wanted to make a new programming language, as far as I can tell. It has some nice implementation aspects but it picked up its users mostly from the Python/Ruby/JS world rather than C/C++/Java, which was the original target market they had in mind (i.e. Google servers). Scripting language users were in the market for a language that had a type system but not one that was too advanced, and which kept the scripting "feel" of very fast turnaround times. But not Java because that was old and unhip, and all the interesting intellectual space like writing libs/conf talks was camped on already.

replies(5): >>44395036 #>>44396542 #>>44396960 #>>44397814 #>>44398191 #
9. hgomersall ◴[] No.44395019{3}[source]
Well it depends what you're doing. 95% is like, just your opinion man. The rust type system allows, in many cases, APIs that you cannot use wrongly, or are highly resistant to incorrect usage, but to do that requires careful thinking about. To be clear, such APIs are just as relevant internally to a project as externally if you want to design a system that is long term maintainable and robust and I would argue is the point when the type system starts to get really useful (rather than diminishing returns).
replies(2): >>44397969 #>>44408932 #
10. rsanheim ◴[] No.44395036[source]
Java still had slow startup and warmup time circa 2005-2007, on the order of 1-3 seconds for hello world and quite a bit more for real apps. That is horrendous for anything CLI based.

And you left out classloader/classpath/JAR dependency hell, which was horrid circa late 90s/early 2000s...and I'm guessing was still a struggle when Go really started development. Especially at Google's scale.

Don't get me wrong, Java has come a long way and is a fine language and the JVM is fantastic. But the java of 2025 is not the same as mid-to-late 2000s.

replies(2): >>44396358 #>>44403007 #
11. bjackman ◴[] No.44395068[source]
I think a lot of the materials that the Go folks put out in the early days encourage a very channel-heavy style of programming that leads to extremely bad places.

Nowadays the culture seems to have evolved a bit. I now go into high alert mode if I see a channel cross a function boundary or a goroutine that wasn't created via errgroup or similar.

People also seem to have chilled out about the "share by communicating" thing. It's usually better to just use a mutex and I think people recognise that now.

replies(1): >>44397884 #
12. ratorx ◴[] No.44395145[source]
This might work for the types you create, but what about all the code written in the language that expects the “proper” structure?

> Types either represent the data or not

This definitely required, but is only really the first step. Where types get really useful is when you need to change them later on. The key aspects here are how easily you can change them, and how much the language tooling can help.

13. silverwind ◴[] No.44395314[source]
You can have the best of both worlds: A fast, but sloppy compiler and slow, but thorough checkers/linters. I think it's ideal that way, but rust seems to have chosen to needlessly combine both actions into one.
14. paldepind2 ◴[] No.44395527[source]
> I guess Google’s years of experience led to the conclusion that, for software development to scale, a simple type system, GC, and wicked fast compilation speed are more important than raw runtime throughput and semantic correctness.

I'm a fan of Go, but I don't think it's the product of some awesome collective Google wisdom and experience. Had it been, I think they'd have come to the conclusion that statically eliminating null pointer exceptions was a worthwhile endeavor, just to mention one thing. Instead, I think it's just the product of some people at Google making a language they way they wanted to.

replies(2): >>44396949 #>>44408603 #
15. danielscrubs ◴[] No.44395624[source]
One day I would like to just change pascals syntax a bit to be Pythonic and just blow the socks of junior and Go developers.
replies(2): >>44397375 #>>44397908 #
16. homebrewer ◴[] No.44395892{3}[source]
Last time I paid any attention to Google's high level conference presenters (like Titus Winters), they almost didn't use Go at all. Judging by the sibling comment, this hasn't changed much. For some reason people are thinking that half of Google is written in Go at this point, when in reality if you listen to what they themselves are saying, it's 99% C++ and Java, with a tiny bit of Python and other languages where it makes sense.

It's just a project from a few very talented people who happen to draw their salary from Google's coffers.

replies(1): >>44398417 #
17. mike_hearn ◴[] No.44396358{3}[source]
Maybe so, although I don't recall it being that bad.

But Go wasn't designed for CLI apps. It was designed for writing highly multi-threaded servers at Google, according to the designers, hence the focus on features like goroutines. And in that context startup time just doesn't matter. Startup time of servers at Google was (in that era) dominated by cluster scheduling, connecting to backends, loading reference data and so on. Nothing that a change in programming language would have fixed.

Google didn't use classloader based frameworks so that also wasn't relevant.

replies(1): >>44398337 #
18. loudmax ◴[] No.44396542[source]
As a system administrator, I vastly prefer to deploy Go programs over Java programs. Go programs are typically distributed as a single executable file with no reliance on external libraries. I can usually run `./program -h` and it tells me about all the flags.

Java programs rely on the JVM, of which there are many variants. Run time options are often split into multiple XML files -- one file for logging, another to control the number of threads and so on. Checking for the running process using `ps | grep` yields some long line that wraps the terminal window, or doesn't fit neatly into columns shown in `htop` or `btop`.

These complaints are mostly about conventions and idioms, not the languages themselves. I appreciate that the Java ecosystem is extremely powerful and flexible. It is possible to compile Java programs into standalone binaries, though I rarely see these in practice. Containers can mitigate the messiness, and that helps, up until the point when you need to debug some weird runtime issue.

I wouldn't argue that people should stop programming in Java, as there are places where it really is the best choice. For example deep legacy codebases, or where you need the power of the JVM for dynamic runtime performance optimizations.

There are a lot of places where Go is the best choice (eg. simple network services, CLI utilities), and in those cases, please, please deploy simple Go programs. Most of the time, developers will reach for whatever language they're most comfortable with.

What I like most about Go is how convenient it is, by default. This makes a big difference.

19. throwawaymaths ◴[] No.44396684[source]
> Types either represent the data correctly or not.

No. two types can represent the same payload, but one might be a simple structure, the other one could be three or twenty nested type template abstractions deep, and created by a proc macro so you can't chase down how it was made so easily.

20. fsmv ◴[] No.44396765[source]
Go has never been in heavy use at Google
replies(1): >>44396985 #
21. melodyogonna ◴[] No.44396949[source]
But those people at Google were veteran researchers who wanted to make a language that could scale for Google's use cases; these things are well documented.

For example, Ken Thompson has said his job at Google was just to find things he could make better.

replies(1): >>44398194 #
22. k__ ◴[] No.44396960[source]
"it picked up its users mostly from the Python/Ruby/JS world rather than C/C++/Java"

And with the increasing performance of Bun, it seems that Go is about to get a whooping by JS.

(Which isn't really true, as most of the Bun perf comes from Zig, but they are targeting JS Devs.)

replies(1): >>44397867 #
23. melodyogonna ◴[] No.44396985{3}[source]
Isn't it heavily used in Google Cloud?
24. the_sleaze_ ◴[] No.44397375[source]
That's what they did to Erlang with Elixir and now there are a lot of people saying it's the Greatest Of All Time.

I'd be interested in this project if you do decide to pursue it.

25. rednafi ◴[] No.44397814[source]
Java absolutely does not fill in the niche that Go targeted. Even without OO theology, JVM applications are heavy and memory intensive. Plus the startup time of the VM alone is a show stopper for the type of work I do. Also yes, Java isn’t hip and you couldn’t pay me to write it anymore.
replies(1): >>44403011 #
26. rednafi ◴[] No.44397867{3}[source]
Runtimes like Bun, Deno, or type systems like TypeScript don’t change the fact it’s still JS underneath — a crappily designed language that should’ve never left throwable frontend code.

None of these runtimes make JS anywhere even close to single-threaded Go perf, let alone multithreaded (goroutine) perf.

replies(1): >>44398255 #
27. rednafi ◴[] No.44397884{3}[source]
This is true. I have been writing Go for years and still think channel is a bit too low level. It probably would've benefited from a different layer of abstraction.
28. rednafi ◴[] No.44397908[source]
Sounds like the guy who wanted to write curl in a weekend. /s
replies(1): >>44404468 #
29. rednafi ◴[] No.44397969{4}[source]
> The rust type system allows, in many cases, APIs that you cannot use wrongly, or are highly resistant to incorrect usage, but to do that requires careful thinking about

I need none of that guarantee and all of the compilation speed along with a language where juniors in my team can contribute quickly. Different problem space.

30. frollogaston ◴[] No.44398142[source]
Same but with Python and NodeJS cause I'm doing less performance-critical stuff. Dealing with type safety and slow builds would cost way more than it's worth.
replies(1): >>44399005 #
31. frollogaston ◴[] No.44398191[source]
Golang having solid n:m greenthreading day 1 was its big deal. Java has had no good way to do IO-heavy multitasking, leading to all those async/promise frameworks that jack up your code. I cannot even read the Java code we have at work. Java recently got virtual threads, but even if that fixes the problem, it'll be a while before things change to that. Python had the same problem before asyncio. This isn't even a niche thing, your typical web backend needs cooperative multitasking.

I'm also not fond of any of the Golang syntax, especially not having exceptions. Or if you want explicit errors, fine, at least provide nice unwrap syntax like Rust does.

replies(2): >>44399022 #>>44399279 #
32. nine_k ◴[] No.44398194{3}[source]
They also built a language that can be learned in a weekend (well, now two) and is small enough for a fresh grad hire to learn at the job.

Go has a very low barrier to entry, but also a relatively low ceiling. The proliferation of codegen tools for Go is a testament of its limited expressive power.

It doesn't mean that Go didn't hit a sweet spot. For certain tasks, it very much did.

33. frollogaston ◴[] No.44398255{4}[source]
JS is perfectly designed for what it does, frontend and non-CPU-intensive backend code. It's never going to reach singlethreaded Golang perf.
replies(1): >>44398983 #
34. frollogaston ◴[] No.44398337{4}[source]
Golang is frequently used for CLIs, even if it wasn't designed for that exactly
replies(1): >>44399977 #
35. frollogaston ◴[] No.44398396{4}[source]
And probably more Java than C++
36. fireflash38 ◴[] No.44398417{4}[source]
K8s isn't entirely in go?
replies(1): >>44399169 #
37. liampulles ◴[] No.44398420[source]
As the story goes, a couple of Google developers designed Go while waiting for one of their C++ projects to compile.
replies(2): >>44400002 #>>44403037 #
38. rednafi ◴[] No.44398983{5}[source]
JavaScript was never designed for non-browser usage. It’s the community’s unquenchable thirst to use the same language everywhere that brought us here.
replies(1): >>44399087 #
39. rednafi ◴[] No.44399005[source]
Python and NodeJS bring a whole lot of other problems. But yeah at a smaller scale these languages are faster to work with.

At the same time, I have worked at places where people had to rewrite major parts of their backend in other languages because Python/Node was no longer sufficient.

replies(1): >>44399119 #
40. aaronblohowiak ◴[] No.44399022{3}[source]
by FAR my biggest complaint about Golang was null instead of Option. could have been special cased like their slice and map and would have been so so so much better than nil checks imho. really, a big miss.
41. frollogaston ◴[] No.44399087{6}[source]
NodeJS about page makes its case pretty succinctly, JS was a good fit for IO-bound concurrent backends because of the event loop. This was at a time when no other major language/runtime had a good answer for this unless you count Erlang. Plenty of people using it didn't even come from the web frontend side, myself included.

npm was also maybe the first default package manager that "just works," unlike Python or browser JS.

replies(1): >>44399889 #
42. frollogaston ◴[] No.44399119{3}[source]
I'd have to see it, cause rewrites happen all the time. We had a system written in C++, then rewritten in Golang because C++ was supposedly not good enough, then rewritten back into C++.
43. frollogaston ◴[] No.44399169{5}[source]
They don't really use K8S internally
44. cogman10 ◴[] No.44399279{3}[source]
Java 21 has n:m green threads, but with caveats. Java 24 removed a major source of the caveats.
replies(2): >>44400277 #>>44400464 #
45. AgentME ◴[] No.44399889{7}[source]
A lot of people don't realize NodeJS was made because the creator wanted to make a runtime dedicated to asynchronous IO, didn't want to use a language with a pre-existing standard library and ecosystem built around synchronous IO, and realized that JS almost uniquely fit the bill. It was not built for the purpose of letting people who only knew JS use JS on the server.
replies(1): >>44400205 #
46. zenlot ◴[] No.44399977{5}[source]
If you want to write CLI tool, you use Rust.
replies(2): >>44400159 #>>44400741 #
47. zenlot ◴[] No.44400002[source]
If we wanted speed compile times only, we'd be using Pascal. No need for Go. In fact, if there would be ever a case for me to use Go, I'd rather go for Pascal or Delphi. But there isn't, it just doesn't fit anywhere.
replies(1): >>44400777 #
48. frollogaston ◴[] No.44400159{6}[source]
Or you use Golang? A lot of the time there isn't a big difference.
49. frollogaston ◴[] No.44400205{8}[source]
This tracks, cause the NodeJS website also doesn't mention anything about people already knowing JS. And imports worked completely differently between browser and Node, so they were pretty separate things at least at the start.
50. frollogaston ◴[] No.44400277{4}[source]
Yeah, I'm hoping that fixes things eventually. We still can't use that at work, and even once we can, there's 10yo code still using 3 different old ways of async.
51. computably ◴[] No.44400464{4}[source]
I'm sure you're already aware but for those who aren't - Java 21 was released in 2023. Golang 1.0 was released in 2012.
replies(1): >>44403029 #
52. rednafi ◴[] No.44400741{6}[source]
Who said that? Go is pretty amazing to whip up great CLIs quickly.
replies(1): >>44400948 #
53. rednafi ◴[] No.44400777{3}[source]
I understand the sentiment as I feel the same about Rust. I’d rather raw dog C++ than touch Rust. Doesn’t make sense and I could come up with some BS like you did and make my case anyway.
54. ◴[] No.44400948{7}[source]
55. pjmlp ◴[] No.44403007{3}[source]
Not when using commercial JDKs, but naturally most HNers never worked on companies that paid for those.

For example initial JIT caching experiments on OpenJDK came from J/Rockit.

56. pjmlp ◴[] No.44403011{3}[source]
The old OOP testament was written by Smalltalk and C++ apostles, then the school of Objective-C belivers was found, and some of the scholars helped with the new Java religion.
57. pjmlp ◴[] No.44403029{5}[source]
In 2012 we could do much of the same stuff with Java 5 concurrency framework and futures (aka promises everyone raves about on JS land), with the advance that scheduling can be customised.
replies(1): >>44405691 #
58. pjmlp ◴[] No.44403037[source]
Yes, because the way Google uses C++, and the developers have well known positions against C++ anyway, coming from Plan 9/Inferno and Oberon backgrounds.
59. danielscrubs ◴[] No.44404468{3}[source]
You’d be surprised. Here is the Pascal successor Oberons very short Ebnf. https://oberon07.com/o7EBNF.xhtml

Something to look into in retirement.

60. frollogaston ◴[] No.44405691{6}[source]
That's what I meant by unreadable code. You have to twist everything to work with whatever async framework.
replies(1): >>44406651 #
61. pjmlp ◴[] No.44406651{7}[source]
Have you ever had to write down channel sending dependencies graph?

I had to, to make sense of whatever was going on.

replies(1): >>44426393 #
62. IshKebab ◴[] No.44408603[source]
And indeed they did come to that conclusion - for Dart 2.

Go is the product of like 3 Googlers' tastes. It isn't some perfect answer born out of the experience of thousands of geniuses.

I think they got a lot right - fantastic tooling, avoiding glibc, auto-formatting, tabs, even the "no functional programming so you have to write simple code" thing is definitely a valid position. But I don't think anyone can seriously argue that Go's handling of null is anything but a huge mistake.

63. IshKebab ◴[] No.44408670[source]
That's not true. There's a spectrum of typing complexity all the way from TCL everything-is-a-string to formal languages like Lean where the types can prove all sorts of things.

As you go further towards formal verification you get:

* More accurate / tighter types. For example instead of `u8` you might have `range(0, 7)` or even a type representing all odd numbers.

* Better compile time detection of bugs. (Ultimately you are formally verifying the program.)

* Worse type errors. Eventually you're getting errors that are pretty much "couldn't prove the types are correct; try again".

* More difficulty satisfying the type checker. There's a reason formal verification of software isn't very popular.

So it's definitely true that "more obnoxious types" exist, but Go is very far from the obnoxious region. Even something like Rust is basically fine. I think you can even go a little into dependent types before they really start getting obnoxious.

TL;DR, he's just lazy and doesn't really care about bugs.

64. bogeholm ◴[] No.44408932{4}[source]
While I agree with your analysis and points, my upvote was based entirely on the Lebowski reference
65. frollogaston ◴[] No.44426393{8}[source]
If this is an app backend, you aren't dealing with Golang channels directly. Your webserver or whatever it is spawns a new goroutine (greenthread) for each incoming request, then you use blocking calls without worrying. Looks similar in JS but the event loop handles it instead, and you async/await stuff. JS webpages and app frontends also don't worry about this.

If this is systems programming, yeah you're reasoning about channels, but that's mostly the same in any language. Golang has slightly nicer support for that if anything.