Python, Node, Java all have to pre-install lots of dependencies before you can use them, fine for developers, not so great if you want to distribute software for people who are not software savvy, who typically just wants to download one file, install and start using it.
c and c++ can also do one executable, but, it is not as portable as Golang, and not as static-link friendly as Golang.
You can ship one compiled binary in Java too if you want it. https://www.graalvm.org/22.0/reference-manual/native-image/
> Go is simple. It's easy to understand, read, and maintain
Go involves a lot of code repetition which makes it difficult to human-scan and maintain. Worked on both large scale Go and Java projects and I found Java projects easier and more comfortable to maintain. Had to pay a lot more attention to Go. Go is easier to write though thanks to its well-designed and extensive standard library which is possibly the best in the world, but the maintenance angle still tilts to Java. There are also more Gotchas in Go compared to Java.
However, the Go code bases I’ve encountered have been less abstract and to the point(even if it means repetition of some little things). I also found it to be free of boilerplate except for the if err != nil part.
I guess those that have spent decades in such abstractions must have learnt a skill to navigate such a spaghetti. But, I still hate it every time.
No matter the amount of abstraction though, one rarely runs into the sort of issues in Java that Go code tend to run into frequently - causing multi-million dollar mistakes frequently even for experienced Go programmers. For loop semantics https://bugzilla.mozilla.org/show_bug.cgi?id=1619047, Unintended variable shadowing, common mistakes in slice appends/copies, slices and memory leaks, defers inside loops, nil interface vs nil, panics in go-routines. There are loads of bugs in OSS projects wrt to these usually repeated again and again.
Go is very simple to learn and very hard to master writing bug-free code. Looking forward to seeing how languages like Rust perform if/when adopted by enterprise.
Even if you’re shipping a jar. You can ship one artifact by using jlink or you ship the runtime in the docker image.
This has been a solved issue for ages.
i think it's a flaw that wasn't considered properly in the standard java toolchain to not produce an embedded java runtime into a final packaged artifact that is self-executable.
You end up with third party tooling like: https://www.ej-technologies.com/resources/install4j/help/doc... (and https://launch4j.sourceforge.net/ too).
If oracle bundled this tool into the JDK, it would've not been an issue at all.
Having AOT compilers as commercial offerings, was seen as one way to capture value in the Java market, in a culture where most compilers were still commercial, GCC being the exception.
In an anemic way, with mostly third party offerings few people know or care about, and various degrees of pain and shortcoming to their use. It should be a first class feature, and as simple to use as is in Go (including for cross compiling).
In general, if something exists in "some form" for 30+ years in a language, and only a handful of people use it, whereas in another it's used all the time and people from other languages are jealous of how well it works, then the formers "some form" is not a good one.
These days there's also GraalVM native image which does produce Go-like results. But with everyone using Docker on the server anyway it doesn't matter anymore. People who talk about single binaries are confusing to me. What are you doing where shipping one file is so much simpler than shipping a container?
Desktop applications.
Java would be a more popular desktop application platform if it weren't for the difficulty in this area (which, to be fair, isn't the only difficulty - cross platform is difficult inherently).
Not really.
I was planning to write a small side-project to generate GitHub Actions boilerplate. And this time, I intentionally chose Go for that exact reason. https://github.com/ashishb/gabo
1. Compiles to native code with a single and very reasonable sized binary on pretty much any platform.
2. Compile to WASM (coming this year) if that’s your thing.
3. Excellent concurrency support with lightweight and simple mental models
4. Variables are not nullable by default thus simplifying tedious checking in your codebase.
5. Syntactically it’s the best parts of Java and JavaScript combined without all the foot guns and verbosity.
6. Full support for both OOP and functional code styles
7. Existing interop support with C, C++, Rust, Java and JavaScript and in the future WASI.
8. Fully static / compile time metaprogramming capabilities coming this year.
9. Also have maybe one of the best teams working on it that I’ve ever seen in an open source project anywhere. They put in a stupid amount of detail and care to try and keep everything pointing in the right direction at a macro level and have really strong levels of transparency around how the language is developed https://github.com/dart-lang/language
Honestly I think it’s critically under-rated and under-used. Most of its common criticisms I see about it are many years out of date.
Same with your second point. I made a big point to explicitly say I think that right now Dart is very underused and has a huge potential outside of Flutter. Quoting that back to me as though it was something I hadn’t considered is equally as confusing.
And its null handling and checking is the worst.
I absolutely hate it. Java over Dart any day.
I’ve never heard this criticism before and have no idea what you’re even referring to here but I am genuinely curious..
You can make an Electron app with JavaScript and ship the binary (or installer) on any platform. It's not a single executable file, but the user experience is the same.
I don't think there's an equivalent in Go that allows you build a desktop app like that (with frontend and backend both written in Go)?
https://conveyor.hydraulic.dev/
It can be used to ship servers, we use it that way for our own servers. It sets up systemd so you don't need to use Docker. But where it shines is desktop apps.
Windows users get a little 400kb EXE that installs/updates your app and then immediately starts it without user interaction required, so it's effectively a single EXE. Mac users get a bundle. Linux, well, Linux users get a deb that sets up the app+its apt repo, or a tarball. Maybe in future a FlatPak or Snap or something else.
It knows how to bundle and minimize a JDK along with your app as part of the release process. Works great for desktop apps.
It's for Electron too, same deal, easier than Forge in my humble and very biased opinion.
Sorry for the snark, but users will undoubtedly be very grateful to them for not considering Electron.
Yes it's bulky and sometimes slow, but it offers a lot of features and allow developers to ship features and updates really fast, while only needing one codebase for all platform.
At least in the past you could also make a single .exe out of it via 3rd party if you wanted, but I didnt use that for 20+ years so maybe its not valid anymore.
You can even go above and beyond with cosmopolitan libc v2, which makes c/c++ build-once run-anywhere: https://github.com/jart/cosmopolitan/releases/tag/2.0
There seems to be some work getting cosmopolitan libc support in Go, but it is not ready like it is for c/c++: https://github.com/golang/go/issues/51900
Edit: There can be some problems with using static, if you are using your system package manager for library dependencies. I would recommend compiling dependencies from source using CMake and FetchContent, this has solved pretty much all problems I have had with c++ dependency management.
Are .war files no longer a thing? ;)
So in Go you make available the library's source code, and the end-user will download it at build time, or vendor it in the source tree.