- “This code is awful, it’s full of all sorts of hacks, spaghetti code, bad practices, etc.”
- “This code must be fine, because the people working on it are smart, and if I think there’s something wrong, it must be because I don’t know the reasons for it.”
The problem is that junior programmers don’t have a good intuitive sense to figure out which of those reactions is the correct one. Sometimes you get junior programmers who are rightly horrified about the state your code is in, and want to fix it. Sometimes you get junior programmers who think the code is awful just because it doesn’t look like the good code they saw when they were in school, or because they don’t know what good production code looks like (which is often in flux).
The responsibility of the senior developer is to protect the junior developer’s opinions about the code like they’re a flickering candle that could get blown out at any moment. The junior developer will either hold onto those opinions and try changing the code, or will decide that they’re wrong—and the key skill you want to cultivate is the ability to make the correct decision.
It’s easy for a senior developer to simply tell the junior developers what the correct answer is, which is in this metaphor, means taking the candle away.
Manager (who was a world class electrical engineer): "why did you reuse this?"
Friend (who was also an intern): "I assumed ${staffEngineer} knew what they were doing and it would be fine to just place it in this design"
Manager: "never assume that anyone knows what they're doing here or at any other organization."
It doesn't have to be actually invented, you can just build everything yourself.
Point is take that mindset ("Never assume anyone else in this organization knows anything"), quickly becomes never trust anyone else, and degenerates to - we'll need to rewrite the gluons (luckily people give up after they spend all their free time).
I prefer the Chesterton's fence. If you don't know what it does you can't remove it.
> I find it is generally a mistake to just bring in dependencies
I don't agree.
It's a pick your poison situation. Use dependency and have a centralized source of mistakes or distribute mistakes, e.g. billions of xml parsers suffering the same issue.
In my experience cautious use of dependencies is preferred, but I would take a well known devil. Over a homebrewed one.
And it's pretty much always a bad choice. It might be a little bad - like if you're using PostgreSQL, you'll need TestContainers for your integration tests, which can slow the build - or it can be a lot bad - like if you're using Oracle, a horde of demonic spirits now know your True Name and are laying plans to extract the most value for their Dark Lord - but there's always tradeoffs.
Senior engineers are just better able to list and weigh those tradeoffs, and maybe hedge against some of the badness through careful architecture.
See: C++/Java OOP implementation.
And when the ship sinks under their feet they somethings don’t accept or realise that the ship is sinking because of choices they made. However the smart ones will learn and make better choices in the future.
Interesting.
How does that fit into the success of Node.js?
Even the author of Node.js accepts that it is dreadful. Yet it underpins so much current technology. Even in the Rust world.