On programming fluency (cont'd)
This article is part of a series on programming fluency.
In the previous post, I covered how I consider programming languages to be similar to (foreign) natural languages, and how one can go about learning the basics. We’ll now move on to how a coder can build on this initial limited knowledge to become proficient in his craft.
Becoming proficient
Read good code
You’d be surprised how much you learn by reading someone else’s code. Not only does it require you to be fluent in the programming language and its idioms, you’ll need to be able to understand the original coder’s intent. Much like listening to different accents helps you differentiate between the sounds that really matter in a foreign language, reading quality code from different authors will allow you to differentiate coding best practices from personal style.
By simply understanding what the written code does, and considering the codebase as well as how you might have implemented an equivalent solution, you will significantly increase your understanding of the underlying programming concepts.
Luckily, in this day and age there is plenty of quality code to read and learn from: simply head over to a repository of open source code (such as GitHub, SourceForge, or BitBucket) and learn! If you expose yourself to good code time and again, and actively think about its design and implementation, how it differs from what you would have done, and why, you should end up with good coding reflexes by osmosis.
Reading good code makes you a better programmer in the same way that reading good prose and speeches will make you a better orator: simply speaking time and again isn’t enough, you must commit time to active study. See how using synonyms impacts the text’s rhythm and tone; listen to great orators pacing themselves through speeches.
Benjamin Franklin is widely know to have taught himself to write eloquently, and it would behoove you to use the same techniques to better your software craftsmanship.
Write new code
Start a side project (or two), and try to apply the new concepts you’ve learned. Much like authors can get writer’s block when facing a blank page, coders get a special feeling when staring at a blank screen, filled simultaneously with excitement and dread. There’s nothing quite like starting from absolute nothingness and producing something that has never existed before.
But making something that previously existed only in your imagination requires expressing your thoughts concisely, in a structured way. Failing that, you’ll soon end up in a miasma of unmaintainable code, and you’ll have trouble seeing how to implement your next feature set.
This process of transforming thoughts and concepts into working code has a direct impact on your retaining new programming concepts: as you’ll have to figure out how to leverage fundamental programming concepts and apply them onto actual code in a situation you’ve never been confronted to before. And this is why, in the previous post, I stressed the importance of understanding underlying programming concepts instead of specific examples.
If you don’t want to start a larger project, you can stick to bite-size challenges, like the Ruby quizz.
Review old code
Try to periodically review old code you’ve written. You’ll be surprised at how often, after even just a few months, you’ll be thinking “my God, how could I have written this?” and “if only I knew then what I know now”…
Not only is it encouraging to realize that you are, in fact, getting better at programming; you’ll also gain a better understanding of why your past implementation choice wasn’t the best, how you’d do it differently now, and why. These "reflective reviews" will also help you develop a sense of style: you’ll find it easier to differentiate code that is nice and tight from code that should be broken down and refactored (possibly using language idioms you didn’t master previously). With any luck, these reviews will also impart you with an instinct for code smells.
Write and rewrite old code
Do your best to find the time to practice code katas over and again. The repetition will drill the basics into your memory and provide you with a fluency in the core language that can only be obtained through deliberate practice. This fluency can later be leveraged into building blocks used to implement novel solutions quicker.
Publish
There’s nothing quite like publishing your code. Once you have users depending on your work, you’re much more careful and considerate about how design and changes affect your software and its users. After all, once something is in production, you can’t afford to simply reload the database schema every time you realize your design is faulty…
If at all possible, try to publish code as open source. You can easily host if for free (e.g. at GitHub, SourceForge, or BitBucket, among others), and publishing open source software will force you to pay special attention to your work: pride is a potent motivator in preventing you from taking the sloppy route. Even if the people perusing your code are only imaginary, the mere fact of exposing your work to the wide world will cause you to think harder about your implementation.
In addition, if you approach the process as providing a solution to a generic problem rather than simply providing your solution to a specific problem, you’ll have to consider the problem space differently in order to ship software that is adapted to a larger set of conditions. This alone will help you to think in more abstract terms and design a more elegant (and ultimately more configurable/maintainable) solution.
Don’t get me wrong: putting your code out in the open is an unnerving affair, but it will make a big difference in your skill level. Aside from the advantages described above, it will give you the opportunity to interact with other developers. I personally found contributing to open source quite intimidating, yet I ended up being added as a coauthor of 2 Ruby gems: SugarCRM and permanent_records. And I can assure you I learned a lot, both from the original code, as well as through implementing the new features and bugfixes.
Beyond languages
I firmly believe that investing time in learning things that aren’t directly related to your language of choice will make you a better programmer. Here are a few things that would be worth your while:
- programming best practices: testing, low coupling, refactoring, etc.;
- investing time in learning supporting tools: source code managers, editors, testing frameworks, etc;
- learning other languages, and more importantly, languages that operate on different paradigms than the ones you’re used to. A great resource for this is Seven languages in seven weeks;
- computer science fundamentals: algorithms, graphs, automata, etc. For a classic on the subject, try on Donald Knuth’s Art of Computer Programming for size.
This article is part of a series on programming fluency.
Would you like to see more Elixir content like this? Sign up to my mailing list so I can gauge how much interest there is in this type of content.