This can be easily done in C and C++, by static linking. In java, by building custom jars. This is in fact common practice in large companies, for exactly the reason you mention.
It cannot be done as easily with interpreted languages (Python, PHP, Ruby, Node.js), though--and those are precisely the languages from which Go has been stealing users.
Vendoring in your dependencies is definitely not hard in a dynamic language, just for some reason most projects never bother. I doubt it's a significant reason why they've been moving to Go.
I think it's more prosaic reasons, like that's the language their job uses. People who use dynamic languages tend not to think of themselves as specialists in their stack.
> Vendoring in your dependencies is definitely not hard in a dynamic language, just for some reason most projects never bother.
Not to take a side in static-vs-dynamic linking or the language argument, but that is absolutely incorrect. Single-static-binary is a very significant reason for lots of people moving to Go: that, plus a good cross-compilation story make a lot of problems go away.
Vendoring dependencies is hard in general. It's much harder in dynamic languages.
Some evidence/examples:
- Look at how many different ways of packaging things that Python has.
- Ruby, which most people consider to be one of the scripting languages that got vendoring right out of the gate, still struggles with system libraries used to bootstrap the Bundler process on deployment targets.
- Node.js, another one which is considered to have gotten vendoring right out of the gate, has massive problems with its implementation: package assets in node_modules take forever to fetch/inflate deployment times and artifact sizes, and put strain on systems. People argue that the difference between "my node_modules directories have so many files I ran out of inodes" and "my golang binary is really big" is just a difference of degree, but it's a big difference regardless.
- Vendoring/deploying compiled/native dependencies are a massive hassle in dynamic languages as well: better make sure that you compiled those deps in a way compatible with your target system (a big hassle if you are, say, building an old Perl C/XS extension on OSX and targeting Linux for deployment), and make sure they all link correctly once there, and, if they link, hopefully they link with system libraries that don't have behavior differences from wherever you tested the code. And a lot of popular libraries have a native component.
- There's also the problem of dependency resolution. Several dynamic languages have hard-coded system library paths, which means that if your vendoring misses a spot, you might be loading an unexpected version of something, or failing to start. The "just put everything in the system lib path" ignores the reality of multitenant/multi-use systems, and as a whole 'nother piece of expertise.
- The popularity of Docker/containers is largely driven by the fact that they let you "statically link" your whole stack. That demand indicates that some folks, at least, found the vendoring story for dynamic languages difficult.
> People who use dynamic languages tend not to think of themselves as specialists in their stack.
This sounds suspiciously like "if you use $language you're an idiot/inferior". Spare me your arrogance and language elitism, please. There are specialists, generalists, experts, and idiots on every platform ever invented--in very, very similar proportions.
The argument was made from devops perspective. Which means, no GC is a show stopper. So that eliminates C/C++. Heck the whole point of languages like Perl was C/C++ had huge practical limitations as languages when one wants to get work done quickly.
Also Java never really worked in Devops. You need to a lot of ceremony to just open files and do simple regex work. Unfortunately Python went down the same path.
In Go it is straightforward to write some code directly on servers and deploy. Java can't be written without its famed heavy duty IDEs and other tools which need full desktop environment not just bunch of command line tools.
You can use static link in C/C++ although you may find that the DLL you're statically linking tend to dynamically load the underlying DLL anyway that defeats the purpose.
In most C/C++ world, you're better dynamically linking anyway due to most prior to Visual Studio 2012 it would determine the Service Pack/Dependencies of your host operating system and include that into the exe manifest.