Reinventing the wheel is the best way to learn. But imo that's really the only context where you should.
I love my rabbit holes, but at work, it's often not viable to explore them given deadlines and other constraints. If you want your wheel to be used in production though, it better be a good wheel, better than the existing products.
If your fencing was done by idiots, then at some point you have no alternative but to start tearing down fences and see what happens. Chesterton's Fence implies either a degree of design or a timeworn quality that most software products don't match.
Chesterton himself was using it as a religious metaphor, and I think most of us agree that software engineers are not literal gods.
Sometimes the reason a fence exists is because the person who put it there was some combination of a) an idiot, b) extremely confused, or c) not qualified to construct fences.
Also, in software, you may find the fence sometimes exists in higher dimensions than the usual three, can turn invisible for part of its length, and occasionally exists but is four inches tall and blocks only mice. And it may also be designed, at least in part, by a blind idiot god called ChatGPT on whose altar consciousness itself is sacrificed. At this point it's worth considering whether keeping the fence around is worse than letting the bull out.
Market-based hypothesis is that the person erecting the fence incurs costs and if the expected value of the fence isn't higher than the cost of erecting it, it wouldn't have been erected in the first place.
Of course mismanagement happens but the implied value of understanding why the fence was erected is to understand the expected value it would bring and understand the problem it was trying to solve. This does not imply that it should have been erected, just that there were others before you trying to solve a problem and if they're failing it's important to know why so you don't fail in the same way.
It's funny. I had a similar analogy with some legacy systems recently. No one seemed to own or know where the data egressed to or whether it was even used anymore.
But it was also low-value data and even in the worst case we surmised the most we'd do is anger someone in marketing briefly.
I think so long as you can ascertain that the stakes are low, this is a good tactic.
It's not really the best way to learn because it's the most expensive and time-consuming. What needs to be learned just needs to be well-documented and possible to tinker with, and clarity of communicating knowledge is a problem on its own, but you shouldn't have to build the whole thing from scratch.
> It's not really the best way to learn because it's the most expensive and time-consuming.
The expense (time or otherwise) follows from how intimately you have to get to know the subject. Which is precisely why it's the best way to learn. It's not always viable, but when you can spare the expense nothing else compares.
No, the expense follows from how many wasted options you'll have to go thorough. The working intimate knowledge can be acquired directly without that waste.
That sounds like learning something only very superficially. Rewriting from scratch is the only way to really learn any topic of non-trivial depth and complexity.
It's not necessarily superficial learning. If you want to learn math, you'd be crazy to rewrite the rules of math just to learn it---you'd be better off with a good teacher and constant practice instead of building the theorems and formulas yourself, or you'll never finish learning math in your lifetime.
Same can be said of learning a large inherited codebase. If you're assigned to a large piece of functionality and you need to understand it, your first instinct shouldn't be to rewrite the whole thing from scratch just to understand it; it should be to either read the code and documentation, or if those are impossible to comprehend, ask around what it's supposed to do, maybe even write tests to get a general sense of the behavior.
I don't expect programmers to be cognitive psychologists here but the thing about learning is that you must do a "progressive overload" of complexity as you go, which is why building on top of what exists is the best way to go. You get a general idea first of what something is supposed to do, and then when you're good enough, that's when you can work backwards to building something from scratch where all the complexity at lower levels of abstraction wouldn't be too much for your brain to handle. Starting with a large amount of complexity will impair your learning and only discourage you.
Sure, you draw the line at different levels of abstraction, but you still need to rewrite from scratch the thing you're learning. If you want to learn how a web server works, you better write one. You don't need to write the OS that it runs on, however, although doing so also informs certain aspects of web server design. Reading the documentation of an existing web server alone is only going to result in a superficial understanding of it.
Different people learn differently. I learned computer science by first learning low-level languages, and then moving up the abstraction tree. Many go the opposite direction.
Personally, I’m a fan of learning by doing. Reinventing the wheel works better for me than just about anything I’ve tried.
I love my rabbit holes, but at work, it's often not viable to explore them given deadlines and other constraints. If you want your wheel to be used in production though, it better be a good wheel, better than the existing products.