“every rust project has a billion dependencies”

oh no they made code composable oh nooooooo should we call someone??

rust has a lot of problems, but let me tell you: “micro libraries” isn’t one

splitting packages per concern is good for build performance, it’s good for review, it’s good for API evolution.

the problems are technical (compiler perf), financial (funding OSS), human etc.

words mean things!!! I’m not happy about the situation either but you have to be precise!!

you have to complain about the right problem!! how the fuck else is anything going to improve????

do your research or be quiet

@fasterthanlime I've been getting a lot of mileage out of this one
@fasterthanlime it's only good for build performance because rustc can't parallelize compiling a single crate very much, which I would say is a problem in and of itself, but otherwise yeah.
@fasterthanlime Honestly, I've never had a problem with Javascript microlibraries, let alone Rust ones. I've never been a huge consumer of them I guess, but it's always been a solid experience.

@ddr @fasterthanlime The main issues I've seen with JS microlibraries are:

1. things that should be in the standard library
2. things where the implementation everyone ends up using is pretty shoddy
3. bad governance leading to disasters due to a commonly-used dependency disappearing or becoming a malware source

and yeah none of those are problems with microlibraries themselves.

I've also seen JS devs be very hesitant to update their dependencies leading to a miasma of security issues.

@ddr @fasterthanlime Why I don't like such packages:

is-number - Claims that numeric strings are numbers but NaN and inf are not.
falsey - Has a weird list of words that are considered false.
to-regex-range - Something that I consider a bad idea.
And apparently it's
heavily used
repeat-string - claiming they have the fastest implementation but turns out it's mostly because of caching and bad benchmarking

All those libraries make assumptions that when not carefully checked will create problems down the line.

Those examples are all from the same author because it was the fastest way for me to find examples.
is-number/index.js at master · jonschlinkert/is-number

JavaScript/Node.js utility. Returns `true` if the value is a number or string number. Useful for checking regex match results, user input, parsed strings, etc. - jonschlinkert/is-number

GitHub
@interru @ddr @fasterthanlime
But NaN isn't a number. That's why it's called "Not a Number"

@kirtai @ddr @fasterthanlime it's part of the primitive type number. Let me quote MDN:

NaN ("Not a Number") is a special kind of number value [...]Names often don't fully convey the full complexity leading to wrong assumptions. is-number doesn't just check for type number but also for numeric strings and NaN is part of type number despite it's name.

JavaScript data types and data structures - JavaScript | MDN

Programming languages all have built-in data structures, but these often differ from one language to another. This article attempts to list the built-in data structures available in JavaScript and what properties they have. These can be used to build other data structures.

MDN Web Docs
@fasterthanlime isn't compiler performance better with micro libraries than with one big code chunk?
@fasterthanlime When almost every one of those micro libraries are version 0.x however...
@mort @fasterthanlime Yeah, as others have noted, the issue with Rust (and Javascript) library dep explosion aren't the explosion itself, they're some of the causes (anemic standard library - Rust doesn't even have datetime!) and the specific contexts (every library is 0.1000.5 because no-one wants to stabilise at a release version, poor choices of repository system leading to "supply chain attacks" etc). Library explosions make this kind of thing hard to *identify*, which is bad.
@aoanla I wanna name another cause of the 0.x problem: there are plenty of packages out there, in version 0.x, which *have* a stable API and which have no trouble promising to keep their API stable. That's *why* they stick to 0.x: releasing 1.0 would break all their dependents, since 1.0 is incompatible with 0.x. If they're on 0.4.3, releasing 0.4.4 is safe: their users will get the new update; releasing 1.0 is risky: many of their users will stay on 0.4.3 because that's Cargo's default behavior
@mort Absolutely, but that's *clearly* short-termism - the pain of dropping a 1.0.0 wouldn't last, and the benefits - including *actually signaling correctly that your package is release-ready and stable* - would outweigh it quickly.
As it is, what they do is avoid pain but also perpetually *look* like they're never going to have a polished product/the package might go away at any time.

@mort @fasterthanlime
good thing then that <https://crates.io/crates/leftpad-rs> is already v1.2.0.

What does a 1.0 mean if anyone can give their library any version number they want?

crates.io: Rust Package Registry

@Kijewski @fasterthanlime The serious answer to the question in your second paragraph is: version numbers are communication. When I want to signal that my software isn't really ready for general use, I use version 0.x. Just like how I increment the major version to communicate a backwards incompatible change.

Conversely, my assumption is that people who version their libraries as 0.x are trying to communicate, "this library is not ready for general use".

@fasterthanlime That is actually a good point, but Rust does not really have those 15 lines of code libraries in the first place as much as JS does. You know, those libraries that should have been a code snippet.
@fasterthanlime micro libs are only an actual problem in an environment like a browser, where code is fetched, tracked, glued together and interpreted for each user. in rust it just makes the build process look busy.
@lime New corporate metric: your productivity is measured in the time it takes the compiler to process your code @fasterthanlime
@lambda @fasterthanlime every go developer is out on the street immediately
@fasterthanlime the problem starts when your dependencies start to depend on different basic things like time/date and now you ship 3-4 incompatible libraries that does the same thing.
@fasterthanlime It does seem to be that the people most eager to claim that modular dependency trees are a problem are those that primarily use languages that aggressively resist modularity. I wonder what that could mean?
@fasterthanlime while micro-libraries still irk me a bit, my issues with them are not really anything i actually worry about

the major issue with the rust ecosystem is the lack of integration with the rest of the system: vendoring every dependency, no easy way to update them without patching the lockfiles of every package a distro may ship, static linking only, randomly building vendored and possibly outdated c libraries inside build.rs (one of the worst ones), etc
@navi @fasterthanlime counterpoint: dynamic linking is a nightmare.
@tedmielczarek @fasterthanlime disagree, specially for distros

but even if you drop the static link point on my post, everything else is way more problematic, vendoring and lockfiles, building random c libs in build.rs
@navi @fasterthanlime I fully agree that build.rs is a nightmare. Everything else you describe is the standard tension between project developers and distro maintainers that is as old as time. 🙂
@tedmielczarek 1.80 releases, breaks the time crate, we at gentoo now have to hunt every rust package that uses directly (or indirectly via a library) and patch the lockfile to use the new version of time

if this was c, c++, or python, or similar, we'd bump the time crate package and maybe trigger a reverse-dep builld, that's it

but rust, (and go and nodejs stuff too, to be fair) require manual patching to bump a dependency, it's kinda really sad and a bit ridiculous imo
@navi I hear you. All I can say is that the needs of software developers and distro maintainers have long been in conflict, and I don't think there are easy answers that make everyone happy.
@navi @tedmielczarek And that's with time being merely broken, not something like a security issue in a widely used crate (and pretty sure so far most distros just ignore this when Rust is involved).

@fasterthanlime I broadly agree, but have gotten feedback on two points: "supply chains" make it hard to understand who you're trusting, and discoverability is hard for people who aren't as well-versed in the ecosystem.

https://www.memorysafety.org/blog/reducing-dependencies-in-sudo/

Sudo-rs dependencies: when less is better

The sudo utility represents a critical privilege boundary, so it should be memory safe. We rewrote it in Rust with partners at Tweede golf and Ferrous Systems. Ruben Nijveld from the Tweede golf team offers his perspective here on one of the greatest challenges we faced when developing software that can be widely adopted: Rust crate dependencies. Josh Aas, Head of ISRG's Prossimo project When sudo-rs development started, we added several dependencies using Rust's crates ecosystem to quickly ramp up development.

@fasterthanlime the problem is that micro libraries have their interface derived from the implementation, and similar problems require a different micro library with a similar but subtly different interface, and neither of these is maintained going forth because they are feature complete as defined by their interfaces.
@GyrosGeier not really a problem I've seen much in the Rust space tbh
@GyrosGeier @fasterthanlime code shouldn't have to be endlessly maintained

we should be able to call a project
done rather than abandoned
@dark @fasterthanlime yes, but that requires a definition of "done" that is not attached to the first (and, in the beginning, only) dependent project, and it requires the interface to be designed around anticipated future needs and in a way that will allow dropping in later versions.
@fasterthanlime a bigger problem is all those libraries shipping with macros amirite

@fasterthanlime
> human

do you mean that a lot of people have the ability to push potentially malicious updates to popular libraries?

@fasterthanlime > splitting packages per concern is good for build performance, it’s good for review, it’s good for API evolution

I do agree with this in the abstract, but there are certain corner cases where many small crates don't work super well.

In Android, we vendor all dependencies and each crate import requires its own approval: someone checks the license, someone else check the unsafe code, etc... We are working on improving the process, but right now, importing 20 crates takes weeks.

@fasterthanlime The problem here is a mix of process and tooling and we're improving both at the moment. Realistically, non-Cargo based projects like #Android and #google3 (based on #Bazel) has to write tooling to align with the expectations of Cargo. We haven't always been super good at doing this, but we're improving 😄