Nevertheless, modules and try... it seems like it’s just an effort to add them all back in again.
Surely if this happens go will be indistinguishable from all the other languages it was designed to be different from?
Nevertheless, modules and try... it seems like it’s just an effort to add them all back in again.
Surely if this happens go will be indistinguishable from all the other languages it was designed to be different from?
Up to this point, the ratio of useful enhancements to unnecessary cruft has heavily skewed towards usefulness.
The post links to a new questionnaire the core wants all change proposers to answer - the questions are pretty good and force a bit of intense soul searching for everyone asking for a change. That will probably stifle ideas a bit, but resisting change by default is what we want out of this language anyway.
I won't say Go dependency management is terrible, but it's certainly not awesome. At least to someone who has used PHP (Composer), Rust (Cargo), JavaScript (NPM), C# (NuGet).
- npm install ignores package-lock.json and uses package.json. The work-around is to use npm ci. https://stackoverflow.com/a/45566871/30900
- Flakiness. An acceptable solution to npm difficulties is `rm -rf node_modules; npm i`. Admittedly, this has improved a lot in recent years.
NPM also inherits the design preferences of the JS ecosystem.
- Simple packages have deep dependency graphs.
- Functionality is spread across multiple packages, sometimes at a granularity of a function per package.
- If you want types, you roughly double the number of packages you need.
Getting types is optional and only required if you use typescript which you don't have to. It does improve the editor experience for vanilla js but those are put under dev dependency.
There are a lot of things that can be improved though.
Lot of packages put their config inside package.json which is honestly messy. The whole script part is a bit restricting. Better approach would have been to follow how mix (elixir) does it. Json is limiting as a format, no comments.
Like you mentioned, it inherits the mentality of js ecosystem. It doesn't feel part of node but a separate piece of its own.
I personally found Maven much more friendly, since there are no odd interactions with your source-control solution, you get all relevant details in the Maven pom.xml. I also find this idea of relying on semver, especially with Go's insistence on renaming packages for major version changes, to be very unpleasant and brittle, especially for internal packages.
Obviously that comes at the cost of coupling with the VCS. Maybe its not worth it. Interesting idea though.
With Maven, you can define your own versioning scheme and easily include the branch as a component of the version "number".
In Go mod, as far as I can tell, you have to have a Semver vMAJOR.MINOR.PATCH version, which is much more difficult to adjust for short-lived branches.
But as a dev? I can drill down to the core (C-b in Goland, jump to definition) of ANY import. Even the entire go toolchain is in go.
ABI/version management of artifacts is a nightmare, every single time.
Using binary dependencies doesn't preclude having access to source code if desired.
Dynamic linking only became mainstream in the mid-90s.
One of the mayor benefits of maven/cargo repositories is that they are configured to be immutable. No issues with deleted repos or deleted/overwritten tags. Once your dependency is published it's there forever.
It seems you're thinking of the old Go dependency management.
The current Go dependency management, Modules, means that you put in the unique name of the Module (which is its URL) and the Semver-compatible version. Then go mod can resolve the exact code you need.
Sure, it's still source-code based, so you don't need to build a JAR file. Of course, that also means you can't have external dependencies that you pull in - you must have everything required to build your go module in that source code.
Go mod also checks version incompatibilities based on Semver and chooses the lowest specific version which matches everyone's Semver dependency specification.
Your source-control server must also know how to act as a go mod repository (it needs to respond to some go mod specific HTTP calls, as far as I could tell).
Now, when you want to publish a new version in Go, you don't build and publish a specific build to some extra repository. Instead, you need to tag some commit in your repo with a Semver version.
If you want to publish a new major version, you need to do much more than that, since any version higher than v1 will impact the name of your package in import statements in Go code (import "github.com/mymod/mypack" will become import "github.com/mymod/mypack/v2" in any code using your module, including internally).
That said, Gradle has git source dependency support as well.
Either they adapt or eventually fade away.
Hence why we get this reboot cycles where new languages get introduced as revolution against the establishment, and a couple of years later are just as feature rich as the ones they were "fighting" against.
The problem is devs are like, "This is a great language! I wish it had all these other feature from this other language I've been using."
Well, just go use that other language.
But at least your response makes it so that they're whining about two languages, instead of just one...
Sadly seems inevitable that all languages will eventually become bloated due to this.
But by then, you've got a lot of code in the new tool. So what you want is a way to do whatever part of the last 10 or 20% of power that you need for your problem. "It's just a small addition!" But there's someone else who needs a different part of the last 10 or 20%, and wants to add that part...
And so you wind up with the new tool becoming as complex as the old tool. And then, as you say, the cycle repeats.
I think that if a tool is going to be an "80% of the power at 20% of the complexity" tool, and remain that, then it has to have an escape mechanism. You've written your 100,000 lines of simple code, and you need 50 lines in a more powerful tool, well, there's a clean way to use code written in a more powerful language for those 50 lines. Then the language can remain one that just has 20% of the complexity (if those in charge of the language can maintain their vision and their stubbornness).
The other is IPC. Go is so dang easy at concurrency, managing data flow, async IO, etc, that I find it really lends itself to working as a cog in a larger machine, usually distributed. Don't like solving problem X in Go? Solve it however you want and just talk to your Go process.
So you have 2 escape hatches which were much less tenable as overall approaches even 10 years ago. So hopefully Go can stay lean and mean. I think it also helps that unlike other systems languages, Go doesn't have any intent on being a catch-all language. Graphics, hard real-time, drivers? You ain't gonna reach for Go. Light scripting, data science, machine learning? Also probably not Go.
I share your concerns, especially around generics.
I'd love to see the reasoning behind breaking minimalist principles; otherwise it looks like complexity drift to me.
Keyword is "extraneous features". 10 years of hard experience showed neither of modules nor a better error handling story (not necessarily "try") are "extraneous".
On the contrary, extraneous is what we get when everybody implements their own ad-hoc solution for those.