3 ms·
The language not being semantically "good" does not change the webserver cross-compilation story being easier and more consistent than every other platform. I w
by 15155 3y ago
The language not being semantically "good" does not change the webserver cross-compilation story being easier and more consistent than every other platform. I wouldn't voluntarily choose to use Go, but this is absolutely one of its "killer features."
C# and JVM languages both require a substantial amount of tooling and runtime support to achieve this "cross-platform" status and it's still really not the same thing as being able to take a 100% Go source repository and releasing native Windows, OSX, and Linux binaries for both ARM64 and AMD64 machines with no additional tooling from any source machine with just a couple of CLI flags.
With Go, I don't have to install a runtime on the target machine nor do I have to hackily bundle one into my binary. I don't have to make sure the runtime version installed on my system is compatible with whatever I am doing. I don't have to paper over the lack of this functionality with Docker.
- neonsunset 3y ago.NET and JVM - both put portability as their main feature since the very first version. The described difference does not exist in reality, at least not with .NET. JVM tooling produces by-definition portable artifacts that require host runtime (easily accessible by just picking the right container image, which is the same as the most popular way to deploy Go workloads). .NET tooling is identical in producing portable assemblies. Alternatively, you can compile it, like Rust, to a single executable file for a target architecture which either includes IL assemblies and JIT compiler or is a native AOT binary. GraalVM native image offers similar (but somewhat more limited) functionality for the Java world. This is identical to what final Rust binary ends up looking like once you include e.g. Tokio and Hyper/Reqwest or a Go one, which, by all means, includes a full runtime. It is also just two flags: dotnet publish -p:PublishAot=true -r linux-arm64. If anyone has one-liner for GraalVM counterpart - please post it.
- 15155 3y agoFundamentally, to "require host runtime" is not the same thing. There's zero reality where the combination of jars, classpath, system JVM version, system JDK version is the same in developer or end-user experience. C# tooling that statically bundles a massive runtime or JIT compiler where most of the host functionality lives is also fundamentally different in internal implementation than what Go or Rust gives you. GraalVM is a true native binary and is the closest thing mentioned here - the tooling still sucks compared to Rust, Go, or .NET.
- neonsunset 3y agoThe "massive runtime" is on average a 20-60MB executable binary (JIT) if you apply trimming (a single flag or build property). It is no different to Go which too includes async runtime with its own threadpool, type system facilities to do reflection and a GC. If you do AOT publish instead (which is about 9MB size for a full web server + threadpool and more) - it will actually outperform Go at trimming unreferenced code once you start adding dependencies (hello 200MB binary sizes or worse in the Go world - it is almost as if there is no free lunch in programming). Do not conveniently ignore these facts - NativeAOT produces true native binaries. If you look at them with Ghidra (with symbols not stripped) - they resemble something like C++ with garbage collector (write barrier calls) and a couple of interface dispatch calls. (I still find it shortsighted and ironic because coming from worse ecosystems to Go naturally feels like a breath of fresh air yet results in developers being stuck in local maxima, ignoring far better options. And it also ends up being the discussion about the publishing model over language merits which Go has few.)