Sunday, April 20, 2014

Lessons learned after (nearly) a year of professional programming.

I turned 23 yesterday (I'm old. I know) and it's nearly a year since I started writing code professionally. During this time, I learned a lot of things about programming. Here are some of my observations.

1. Code is for people, binary executable is for the machine: This is a recurring theme which one reads about and something everyone knows but its so hard to remember this principle while coding and get carried away. In two weeks, no one, including the author of the code remembers why the code was written the way it was. I am not talking about commenting code here. Although its important to comment your code, a sign of a good programmer is his/her ability to express themselves as clearly as possible with their code alone.  Comments should be minimal, and code itself should tell its story most of the time. 

2. Respect your data types: Store strings as strings, numbers as numbers, ObjectIds as ObjectIds and dates as dates, avoid *manual* conversion of types from one form to another as much as possible because it only leads to pain and unnecessary code in the form of conversion routines. A bug in a conversion logic can be catastrophic.

3. Interface before Implementation: Write down what interfaces your entities will expose without worrying about how they are gonna do it. Its hard to keep these two facets separate when thinking about code but its an important skill which you have to develop. Think about interface first, and write it down because its volatile and a minor change can impact anyone who is relying on that interface, also, get a sign-off from all those who develop/rely on that interface.

4. Beautiful Code when you can, Beautifiable code when you can't: The ideal code contains zero 'if' statements, no loops and can be read like a novel. It doesn't use globals, doesn't maintain much state anywhere and exhibits all the characteristics of good code you  have ever read about, anywhere. However, due to constraints of time, development that happens elsewhere which you rely on, the libraries and frameworks you use, its almost impossible to achieve the 'ideal code' which everyone desperately wants. When you are in complete control of all the environment variables, write beautiful code, when you are not, write code to finish the feature, however, ensure that it can be 'beautified'. That is, your code must be easily refactorable even if its not completely refactored.

5. Decide on suitable defaults beforehand: Variables will be undefined, uninitialized, database columns will hold nulls or will be non-existent,  parameters passed in may be null/undefined. In all such cases, its important that your code function properly and not choke. Specifying default behaviour in all cases will almost always be impossible, however, you should identify the most common cases where there is a high likelihood of something like that happening and define application behaviour. It should be documented, preferably with comments. Timezones, internationalization and unicode support are some of the things you should worry about before writing a single line of your application code. Also, do not mess with usernames! make no assumptions about them. All bets are off if you do!

6. Workflow is a habit: One of the most time-consuming aspects of writing code relates to the workflow which your team follows. Its not uncommon to get into all sort of troubles with your development environment and version control you use (use git. Its awesome.) and spend hours trying to resolve those problems. The time spent doing that cuts into the time which you could have spent thinking about how you could structure your code better( or playing 2048 while taking a break). Sometimes you have to get your environment back to a sane state, it happens. But, if you make your workflow a habit you follow religiously, your "muscle memory" takes over and you find yourself producing code in such a way as to cause minimal disruption for yourself and for others. A few things I follow obsessively are: committing or stashing stuff frequently and rebasing the hell out of my commits before I push code.

7. Integration implications: It's important to clearly specify how a new feature fits into the overall application. What are its side-effects on already available features of the system? How easy is it to use? Who benefits most from it? What is the risk involved? Will the application exhibit unintended/ seemingly inconsistent behaviour because of this addition? These are the questions you should ask and answer even before deciding the color of the button which invokes the new feature. The sooner you get these details straight, the better your resulting code is going to be. Its imperative to answer these questions before starting the design because any change which needs to be accommodated (with respect to the above posed questions) after the design is finished will be costly to fix.

8. One way: Perl programmers will tell you "there is more than one way to do it". Pythonistas like myself laugh at them. In Python, "There should be only one straightforward way to do it." This is a powerful belief which forces you to think about the best way to implement something. It eliminates  unnecessary trains of thought that lead you away from the best solution. People disagree with me on this, but I believe its important to assume there is a right and most straightforward way to accomplish something and it alone must end up as code. 

9. Functional all the way: Functional code is better. I rest my case.

10. Master the tools you use: Learn how to use your editor efficiently, build your "muscle memory", and master the devtools you use. Debugging tools, diff tools and commands that let you profile something, measure stuff, code quality tools and other aids are essentials when you write code. 

The ideal state which we must aim for is to write good sub-consciously. The master programmer writes code without thinking about what he/she is writing. The fingers automatically hit the right keys and the code writes itself. Of course, what I am describing here is the highest possible state (something akin to a kung-fu master who just moves while fighting without thinking) this can only happen with masters, but its something that we must aim for.

These are some of the things I picked up after 11 months of writing production code, by watching how people (who are much better than I am) write code, and observing myself while I code. Coding is a craft and creating beautiful code is a pleasure in itself.