Hacker News new | ask | show | jobs
by slededit 2747 days ago
Even in C with its tiny standard library you don’t see this kind of explosion. There has to be more to it than that.
4 comments

The problem is that it is far too easy to publish a new library that contains a single function. Due to history and other considerations, this is much harder in C (you have to wrangle CMake or autotools, and then package your library for distributions).

While I do think making things easier for developers is a good goal, making the wrong things too easy (that is, making libraries that become very heavily depended on) results in the problems of Node.js (and I would argue the same is true for Rust). Maybe I'm just a curmudgeon, but I really have a sour taste in my mouth when I look at how Node.js and Rust do library management -- it's making it too easy to make a small library which doesn't really work and then people depend on it.

I once tried to write a simple IMAP cloning utility in Rust and found 4 IMAP crates -- none of them worked properly and all of them incorrectly handled several core parts of the IMAPv4 spec. I figured out later that they all appeared to be forks of one another (or they copied each others' APIs), but that doesn't help matters -- why are forked crates taking up more space in the global crate namespace? The "imap" crate doesn't implement IMAP properly!

Python had this problem (in a lesser degree) too with pip, but I think having a larger standard library and lots of time to mature allowed them to overcome it.

"I once tried to write a simple IMAP cloning utility in Rust and found 4 IMAP crates -- none of them worked properly and all of them incorrectly handled several core parts of the IMAPv4 spec. I figured out later that they all appeared to be forks of one another (or they copied each others' APIs), but that doesn't help matters -- why are forked crates taking up more space in the global crate namespace? The "imap" crate doesn't implement IMAP properly!"

I noticed this problem with Perl and CPAN: there were dozens (well, several) email-sending packages, none of which were near complete. (Speaking SMTP is easy, an actual MTA is hard.)

I suspect there are similar issues in Java-land, although I haven't used Maven-derivatives enough to find out.

It's the wave of the future: make it really easy to share and use libraries, and get a crap-ton of low-quality libraries.

>>> As a C++ developer I can’t imagine 1700 dependencies in a relatively new code base.

>> I think the answer is everything in your standard library plus some of the stuff you would use 3rd party dependencies for in your own project.

> Even in C with its tiny standard library you don’t see this kind of explosion.

I think one of the largest factors is that client-side JS doesn't have a good solution to the problem of dead code elimination.

There are solutions like Google Closure (the JS-to-JS complier), but it's difficult to set up and not many people use it. Instead, it seems like people have moved to lots of small dependencies so they can essentially do dead code elimination by hand.

Webpack?
npm handles sub-dependencies with ease so people aren't afraid to pull in smaller dependencies.

Also since the code has to be downloaded (or uploaded to small lambdas, for example), JS developers are generally weary of depending on large libraries.

>Also since the code has to be downloaded (or uploaded to small lambdas, for example), JS developers are generally weary of depending on large libraries.

Isn't a dependency tree of thousands of small, interdependent libraries essentially just a large, distributed library?

Is there really a benefit to that versus compiling those dependencies to a single file, especially given how many NPM packages are just a single small function? The end result in many cases would probably be smaller than a lot of old JQuery plugins.

> Isn't a dependency tree of thousands of small, interdependent libraries essentially just a large, distributed library?

Yes and it's a thousand times worse than a single, large library.

I think with C in particular it's counterbalanced by it's extreme compile times forcing devs to be picky with their libraries.

Another factor that probably helps is that most operating systems are built off C derivatives and thus usually are already carrying common libararies as dlls

It's not the compile times that keep C codebases slim, it's the primitive build system. There's no notion of modules, so every project has to cobble together an equivalent thing, generally relying on make, autotools and its successors, and the result is both incompatible across projects and incompatible across slightly different build environments.

It's a failing of the Unix model with a small silver lining in that C projects tend to go out of their way not to have to make the build any harder than it already is.

> C in particular [...] it's extreme compile times

How so?

Simple really, the more static libraries you add, the longer it takes. This is most pronounced in the libraries themselves that usually don't risk the performance hit of using dlls, so you get less dependency-of-dependency.
Compile times are not extreme for C, only for C++.
SQLite, which is a single 6MB .c file compiles in under a second in any compiler and under 0.01 seconds with tcc.