This afternoon my intern asked me this simple question. She's a new developer, and a friend of hers is working in a fresh codebase, with best practices. Everything is nice, and he can keep the entirety of it in his head. She's working with my team, Support Engineering. We're the front-line bug squashers at our company. We've got a legacy codebase with no tests and brain melting insanity around every bend.
So she asked me which environment I'd want to be working in if I was her. The question, and the answer speak a lot to what it takes to become a great programmer.
What I would want if I was her is simple. I'd want to be working in the new codebase. There's no question. A new codebase is always more enjoyable to work on. But, what I would want is not what I would recommend with 19 years of professional programming experience.
My suggestion was that right now she was in the best place she could be: debugging a bad codebase with good instincts and helpful mentors, and that's why I'm writing this.
I firmly believe that the most important skill you can learn as a programmer is how to debug: how to debug well, and how to debug fast.
New codebases are great, but they're like kittens. One day they're cute and fun, and the next thing you know they've grown into a tom cat who's running around spraying your furniture. It'll be too big to hold it all in your head, and large swaths of it will have been written by other people. Even if you're really lucky, and people have written great tests, and some god has smiled down upon you and granted you the only significant codebase with no bugs, you'll still need to use your debugging skills.
In the typical case you'll need debugging skills to figure out where the problem is, and then what exactly is going wrong. In our mythical perfect codebase you'll need to figure out where a feature is implemented and how it works in order to build on it. There's really very little difference: hunt something down, understand it, make some changes, write some tests, move on.
People with bad-ass debugging skills get things done faster, in any industry.
That's just the start of why our situation is a better one for her than the happy-fun-land her friend is in. New developers haven't experienced pain yet. They've seen the patterns books but they haven't internalized the problems that resulted in those patterns. They won't know what problems those patterns were designed to avoid, so they won't know when they're about to create that problem. I think that even if they were to go read the best pattern book for their situation they wouldn't be able to truly appreciate it because they don't know the classes of problems they've got to deal with.
Debugging a legacy codebase though... If you've got good instincts, or good mentors (preferably both) you'll be able to see all the ways to not do something. You'll encounter things that just feel wrong, and have people who can explain to you why they're wrong, or what piece of the puzzle you're missing. Once you've found the bad, you'll have to figure out how to make it good, and you'll learn about tradeoffs, because professional coders rarely have the luxury of refactoring everything to be the best it could be, especially in crufty old legacy codebases. No, you have to find the balance. You have to figure out what you can do to improve the situation without spending so much time that the other bugs pile up. It's a lesson I'm still learning nearly 20 years in.
When she eventually moves on from her job as a professional bug slayer she may not know the right way to write good code, but she'll definitely know how to not write bad code, how to make code that other people can understand (because she had to wade through so much incomprehensible stuff), and why you don't violate encapsulation.
A year from now her friend will just be starting to experience the consequences of his inexperienced decisions. A year from now she will be ready to tackle anything.