Hacker News new | ask | show | jobs
by tptacek 1575 days ago
Two major things:

1. It compiles statically down to machine code; there's no JIT or bytecode interpretation execution path.

2. It offers straightforward control over the memory layout of your data structures (it doesn't offer straightforward control over the lifecycle of your memory, which is the next step towards the metal that Rust takes).

The advantage is that casual Go code is generally going to be more efficient both in execution and memory usage than a casual program in a higher-level language. You can make Java do almost anything; the important thing is what languages make easy, not what they make possible.

1 comments

When the actual machine code is generated is irrelevant to the level of abstraction. There have been JIT compilers for C, and ahead-of-time compilers for C# and Java, and that changes nothing about how close to the metal any of them are.

Memory layout is a valid point though. C# with its value types gives you a lot more control than Java does, but is still often grouped with Java, and I think rightly so. Go's pointers go quite a bit further, but then on the other hand, it also has high-level data structures like map as language primitives, which makes it less close to the metal as far as I'm concerned.

I'd personally group all GC'd languages in roughly the same class here, but I think it's reasonable to disagree or make finer distinctions.

By that logic, every language is equivalently close to the metal when it comes to execution, since they can all be JIT'd one way or another. It's a colorable argument but not one most practitioners would agree with.
No, I would agree that something with a smaller runtime might be considered closer to the metal, I was talking about level of abstraction, which I think is different. One example is that a typical C code that depends on a libc is farther from the machine than C code that runs without a libc. Both might use very similar styles.

I'm also not saying JIT vs. AOT is an irrelevant distinction in practice -- like everyone else, I like my programs to start fast. But in the end, you have machine code in RAM either way; the level of abstraction is, all else being equal, the same.

The precise details of how that machine code gets there change nothing about how the program is written. The emphasis people put on those details aren't always warranted. I don't think they matter at all for typical backend code, which is one of Go's main niches.

Edit: The earlier version of this response was maybe unnecessarily pointed, I expanded and toned it down a bit.