Learning to code, whether done through a system like Treehouse or independently, can be a heck of a journey. Much has been written about the early bouts of confusion, impostor syndrome and debugging purgatory that often turn the outwardly ambitious into the seemingly masochistic. No doubt, the above phenomena are quite real and to varying degrees, they can represent useful and edifying phases in the growth of a developer. Certainly, being “stuck”, making mistakes, rooting out answers and good old-fashioned hard work have their place, but often in learning to program, we allow ourselves to wallow too long, simply accepting extended “frustration” or repeating bad habits longer than we should.
With that in mind, I submit my first* formal reflection on how I might have better guided and structured my own early coding efforts. Particularly, I’d like to highlight some of the habits I’ve now internalized, which, if I had acquired earlier, would no doubt have saved me loads of time and gray hairs.
1. Look It Up. Everytime.
As a kid, I remember seeing some particularly methodical students reading novels, but always with a dictionary at the ready. At what seemed like annoyingly short intervals, they would put down the novel, pick up the dictionary and look up whatever word they couldn’t define. We were reading the same novels though I couldn’t bear to think of constantly interrupting the flow of the story with something as sterile and uncreative as leafing through a dictionary.
When you learn to code – especially when you work through materials which may not be carefully sequenced or curated – you are often confronted with jargon, concepts or syntax that is unfamiliar to you. In the case of reading a novel, it’s often pretty easy to infer the meaning of a word from context, in programming, less so. If we treat every unfamiliar word or concept as new sub-lesson we must complete before proceeding, we might send ourselves on an endless string of tangents, without ever completing our original task. This very realistic concern will often cause a budding developer to err too far on the side of – “I don’t need to know this now, I can skip it”.
My suggested habit for reconciling the desire to move forward, with the nagging feeling that we should be digging deeper as we go, is to Look It Up, right from the start. Now, when I say look it up, I don’t mean you necessarily launch yourself into full exploration of the new term, but rather you engage in a quick triage. Essentially, you should stop the task at hand and in the course of a minute or even less, assess where the term or concept fits into your current understanding. From there, you can decide if it’s:
1) Something simple and relevant that you can fully digest in a few minutes. If so, do it. It may not be essential to your current task, but over time it’ll help you build a much broader and stronger foundation.
2) Something important, but not imminently essential and too complex to get into now. If this is the case, try to “get” the one-sentence definition and jot it down on a running list to revisit in depth when your schedule allows.
Or, 3) Something that just isn’t relevant in the short or mid-term. In this case, you can simply return to the original task.
By instituting the above habit, you’ll find that you can both stay on task and learn more as you go, all while getting a better understanding of the ever-growing programming landscape.
2. ASK!
People fear asking what they perceive to be stupid questions, or more precisely, newbie questions. This fear is understandably exacerbated in a space like programming where the “helpful” answers we find in places like Stack Overflow are often needlessly complicated and/or chastise the asker for their admitted lack of understanding. Add to this a never-ending lexicon of acronyms and jargon and it’s no wonder many are hesitant to raise their hand with a question.
My solution to this is two-fold. First: as you learn, jot down the best people and resources to ask and keep that list handy. Sometimes Google or Stack Overflow will lead you in the right direction, but often bloggers specific to your area, Youtube, original documentation or the guy at the desk next to you will be the most appropriate. Second: Get. Over. It. Any “embarrassment” you might feel in asking a silly question early on will be dwarfed by the embarrassment you’ll feel when you realize you’ve been doing something wrong for years, simply for fear of asking.
3. Clean Code, Right from the Start
When you first learn to code, just getting it to compile is often a major triumph. When the code actually does what you intend, it can feel like it’s time to break out the bubbly. At some later date, you will probably discover the wonders of refactoring, identifying code smells and what it means to write clean code.
I personally was amazed to find that writing clean code was as much a practice in keeping my syntax tidy (little things like proper indenting/spacing) as it was much broader guiding principles like “having methods just do one thing”. The irony of some of these rules is that they are both conceptually very simple and have powerful and far-reaching implications in learning to code.
Not everyone agrees on what clean code is, but in general it is something any novice programmer can spend a short amount of dedicated time learning and then putting into practice immediately. Moreover, it doesn’t run the risk of becoming a time-suck or leading to greater confusion, like so many other digressions can. In terms of bang for your buck, clean coding practices are about as good as it gets.
4. Use Version Control
Whether you choose Git, Subversion or TFS Version Control, you should use something, even early on. Version control systems aren’t difficult to use, but using them correctly and getting into the second-level functionalities can take some time. Having good practices in this area is simply fundamental to modern-day programming and essential to working on a professional team. You don’t want to be honing your Git skills on the spot when you land your first Jr. Developer role, so if you aren’t familiar with version control already, it’s time to dive in. Despite the power of these tools, don’t fear getting your feet wet; it will quickly become an eye-opening and time-saving pursuit.
5. Raid the Bathtub and Grab Your Rubber Ducky
I had been programming for several years before I ever learned what Rubber Duck Debugging was. Though it is certainly useful for debugging, it is equally useful for solidifying new concepts and sketching out plans for your code or information architecture. While many new developers will stumble upon this method for making sense out of chaos, we often fail to use the tool as often as we should. In a job where getting stuck for hours is a matter of course, we should be much quicker to reach for the tool which we know can often get us unstuck within minutes.
6. Work in Parallel
Programming can be a very focused task, it is part of the reason while it is such a great flow activity and conversely, why you can spend so long spinning your wheels, often when you know what you are trying probably won’t work. Often, our propensity to keep ramming our heads into a known wall is bolstered by the fact that we feel we can’t make any progress before clearing the roadblock immediately in front of us. Most often, this isn’t actually the case.
After years of daily coding, I know now that in terms of long-term productivity, it’s always good to have at least two meaningful tasks to work on at any time. When you are stuck on one, it’s very often emotionally helpful to simply switch tasks and know that you are still going to get something useful done. Additionally, much like talking to a rubber duck can get you unstuck, simply leaving the roadblock in favor of some other task will often allow you to subconsciously come up with a different solution. Alternatively, if you needed to ask a question, like I suggested above, you can guiltlessly move forward on your parallel task while you wait for a response.
7. Circle Back to What You Know
If there ever was a constantly evolving field, software development is it. As such, you can expect that much of what you should learn will change over time. Your understanding of debugging may have been sufficient for a small project, but when you begin tackling a larger legacy project, it’s probably worth explicitly revisiting. Your facility with your IDE or SDK may be high for a novice, but as you become more advanced, the more powerful features – perhaps those added in recent updates – are worth seeking out. Similarly, the conception you have for of a fundamental idea like Object Orientation or Polymorphism might be appropriate for a novice, but now that you are more advanced, could benefit from an upgrade. Simply put, it’s worth “re-reading-up” on some of those terms, jargon, concepts and acronyms that you may have had to look up when you first got in the game. Much like we can always benefit from refactoring code, we can also benefit from refactoring and refreshing the tools and principles which drive our work.
Alright, you’ve read this far, I know you’re still here. That suggests you aren’t the type of person to let all of this effort go to waste. I promise, I’ll wrap this post up just as soon as you do one thing for me (well, really for you) . . . grab a post-it or open your calendar – scan through the list above and give yourself 5 short to-do’s of things you could relearn, items to look up, practices to implement, links to visit or people to ping. Bad habits are hard to change and there’s no time like the present.
* They say hindsight is 20/20, though given how often I seem to revise things I’ve already reviewed and revised, I’m beginning to think that they are being overly optimistic.