This talk rocks
Great talk, I do think a lot of it is not just culture but the tooling as well.
NPM makes it really easy to just install something.
Rust/Cargo makes it fairly easy, but then you have to do configuring of features which adds a little friction.
Handles transitive dependencies easily, so before you know it you have a lot of them.
Go took so long to get decent package management that it is already in the culture to not add them.
Python is a mess, so you don’t add them because you don’t want the headache.
I’m really happy with how Zig has landed: decently easy to add, but locked to a commit, you have the friction of setting up build.zig to get it wired in how you want it. Plus the culture on top helps.
And let’s just not even talk about C and C++.
There are package managers, buuuuut…
But as far as Zig is concerned, I wonder how it will turn out in the long run.
Go took so long to get decent package management that it is already in the culture to not add them.
I actually disagree here. I have seen more Go projects than I would like which import many packages even with Go’s decently big standard library.
But it’s also often understandable since some of the stuff just isn’t something you would want to do yourself, but not always.
Actually, I think there’s often a decent correlation between standard library size, tooling quality and dependency amount with standard library size and tooling quality being inversely correlated to dependency amount (as in bigger standard library or worse tooling => fewer dependencies).
Or, I would say, it’s people. Depdendencies, libraries, tooling, are people.
Programming languages which are more intuitive to reach a lower level and easier to expand to a higher level often go with fewer dependencies. This is why you see those C + Lisp, C++ + Lua, and Zig + Roc, or pure Zig stuffs, but you seldom see pure original JavaScript or Go + Lua or something like that.
The reason is that, ultimately, dependencies are people. If you need more people’s helps to reach a certain level, higher or lower, you will need more dependencies.
The decision of using dependencies or not always comes from people’s initial work experiences (which is good) and the culture those experiences then further forming (which is questionable).
I have recently taken to the forking + attribution workflow and I like it quite a lot; I think @MasonRemaley / Games-by-Mason’s libraries are awesome in that they work very well both as direct dependencies and as a great base to fork from. Keeping a narrow scope seems to be an important component of that.
I have too, but I wonder how many of those are recent transplants from other languages. If you come to Go from the other languages, you may reach for packages not knowing that the standard library does a lot for you.
Well, some of the projects I linked are decently old projects, like Docker, Podman and Forgejo.
I’ve found that LLMs play an interesting role in my use of dependencies, often obviating the need to vendor them at all. For example I needed a png encoder, and instead of some heavy fully-conforming implementation, I just had an llm produce exactly what I needed in a hundred or so lines of code.
Which is basically the entire training data as dependency! And I’d never trust that unless hand-checking everything myself. At which point I’d rather do it myself, or copy those hundred lines from zigimg with a copyright notice.
I think you’re overstating the amount of time it takes to review a hundred lines of code and understating the effort it would take to surgically remove functionality from an existing project. But to each their own!