Keep in mind the rule of thumb that a employee costs twice their salary, so that would be a 206k/year salary. Generous for some, low for others. The salary spread in the US is crazy.
I'd guess that in 99% of cases, if the borrow checker is a problem for you in Rust then you are likely not ready yet for C or Zig, particularly when you need to work in a team where mainatainability by others is critical.
There are some cases the borrow checker requires you to go through hoops for but I see that as a win for adding friction and raising visibility of weird patterns.
And yes, there are cases that can't be expressed the same way,
Well said! Having a mental borrow checker running in background certainly helps a lot when coding in Zig. What also helps is that Zig safety checks generally catch lifetime bugs at runtime nicely. E.g., undefined memory is set to `0xAAAA`, which, if interpreted as a pointer, is guaranteed to be invalid, and fail loudly on dereference.
It’s also true that people overestimate how often the “weird” patterns are needed. 9 times out of 10 it’s the programmer who is missing something, not the borrow checker.
That has not been my experience with it, but I understand if it is yours. I have often seen people use convoluted or slow patterns to satisfy the borrow checker when something slightly un-kosher would have been simpler, faster, and easier.
Unless a shared dependency gets updated, RUSTFLAGS changes, a different feature gets activated in a shared dependency, etc.
If Cargo had something like binary packages, it means they would be opaque to the rest of your project, making them less sensitive to change.
Its also hard to share builds between projects because of the sensitivity to differences.
I talked a bit about this at the Rust All Hands back in May.
A lot of Rust packages that people ust are setup more like header-only libraries. We're starting to see more large libraries that better fit the model of binary libraries, like Bevy and Gitoxide. I'm laying down a vague direction for something more binary-library like (calling them opaque dependencies) as part of the `build-std` effort (allow custom builds of the standard library) as that is special cased as a binary library today.
While I agree about not having hard and fast rules, like LoC per PR, the principles of this are very relevant.
When reviewing a conglomerate commit in a PR, I have to reverse engineer how the different changes interact to figure out the intent. I then have to do this on each update they make. Contrast that to when someone breaks up their commits where I can zoom through variable renames, extracting functions, etc to see the one line that change that all of that unblocked that makes the difference. Then if updates are pushed, I only have to worry about the commits that were updated.
As for all commits compiling, that is helpful to review the individual commits.
Both of these (small commits, all compiling) are also great for bisecting. You get pointed to a very small change that you can more easily analyze vs dealing with breakages or having to analyze a large change to find what the problem is.
I see stacked PRs as independent of this. PRs are a good unit of cohesion of changes, particularly changes that only make sense if later changes are also merged.
Agree with the overall sentiment but disagree with
> A good rule of thumb is 300 lines of code changes - once you get above 500 lines, you're entering unreviewable territory.
I've found LoC doesn't matter when you split up commits like they suggest. What does matter is how controversial a change is. A PR should ideally have one part at most that generates a lot of discussion. The PR that does this should ideally also have the minimal number of commits (just what dossn't make sense standalone). Granted this take experience generally and experience with your reviewers which is where metrics like LoC counts can come in handy.
It’s often an inverse correlation in well functioning environments. Controversial changes and bug fixes are small and targeted and are deeply reviewed for unintended side effects, while large change sets are often new work that’s been discussed upfront and follows well established patterns and gets waved through.
Good luck getting 90% of devs to commit (har har) to this level of history surgery. Of the ones that actually know how to do it (a small fraction of your typical engineer) an even smaller fraction of that is going to have the patience to do it correctly. You’ll tell devs to do this kind of thing and you’ll either have their eyes glaze over from lack of understanding, annoyance at the extra work, or nodding then apathetical disregard. The one top engineer will do it then be frustrated that the rest of the org doesn’t do proper commit hygiene.
It’s not really something you can easily enforce with automation, so basically unachievable unless you are like Netflix and only hiring top performers. And you aren’t like Netflix.
You also need tools that support the workflow. I love small self-explanatory commits. In git, it's easy to do. Recently I switched to a Perforce organization and it's a disaster. P4 doesn't support stacked CLs and it dramatically hurts engineering quality. Everyone lands mega-CLs because it's the only supported workflow.
Have you tried using the git adapter to Perforce backend [1]? It should let you avoid mega-CLs. When Google used to use Perforce, an internal somewhat similar but a bit more advanced tool git5 was very popular.
The adapter breaks down on sufficiently massive repos. Unfortunately, there's a reason Perforce is still in use despite no one liking it. Git scales via sub-repos, but those have their own drawbacks, and no one is enthusiastic enough about this to champion it.
This comes across as not being self-aware as to why security as laughed out of rooms: I read this as you correctly identifying some risks and said only offered the false-dichotomouy of solutions of "risk" and "no risk" without talking middle grounds between the two or finding third-ways that break the dichotomy.
I could just be projecting my own bad experiences with "security" folks (in quotes as I can't speak to their qualifications). My other big gripe is when they don't recongnize UX as a vital part of security (if their solution is unsuable, it won't be used).
This is how our security lead is. "I've identified X as a vulnerability, recommended remediation is to remove it." "We literally can't." He pokes around finding obscure vulnerabilities and recommends removing business critical software, yet we don't have MFA, our servers and networking UIs are on the main VLAN accessable by anyone, we have no tools to patch third party software, and all of our root passwords are the same. We bring real security concerns to him like this, and they just get backlogged because his stupid tools he runs only detect software vulns. It's insanity.
I've been a web developer for over two decades. I have specific well-tested solutions for avoiding external JS dependencies. Despite that, I have the exact same experience as the above security guy. Most developers love adding dependencies.
> The problem is that sometimes library may need to pin a dependency version.
We on the Cargo team have been working to educate people on the problems with pinning in Cargo.toml instead of relying on Cargo.lock
> Then the library authors may want to use newer language features on their API. Then they simply bump the library mayor version and maintain only that. So an old dependencies will not get updates.
Thankfully, the ecosystem has mostly settled on build requirements not being subject to SemVer and bump Rust versions in compatible releases. There are a few hold outs.
I wouldn't say I'm a dependency maximalist but it not far off.
Yes, shared code has costs
- more general than you likely need, affecting complexity, compile times, etc
- comes with risks for today (code) and the future (governace)
But the benefits are big. My theory for one of the causes for Rust having so many good cli's is Cargo because it keeps the friction low for pulling in high quality building blocks so you can better focus on your actual problem.
Instead of resisting dependencies, I think it would be better to spend time finding ways to mitigate the costs, e.g.
reply