Although it’s not yet the last month of the year, I was in a reflective mood, and jotted down programming lessons I learned this year:
- Spend time first on what you’re going to do, iterate several times on the “plan”, and when you get to the computer, it should just be about typing out what you have already decided.
Of course, I do my own planning within OrgMode itself, it’s hard for me to do my planning on paper, but the idea is to do the iteration of the steps first, take feedback from stakeholders, etc. The actual part of typing should come last and should be boring.
There are places where this should probably not be applicable such as explorations of technology and finding out what is possible, but for majority of things, I constantly have to remind myself that we are in the problem-solving business first, and in the programming business second.
Part of the problem-solving is in figuring out the repercussions of making code changes and how to restrict the limitations and expand the possibilities of the code that we write, especially keeping the code as slim as possible. In simpler words, part of the time spent up front should be as much about the accidental complexity as well as the incidental complexity.
- “Working in strange environments is a CS life skill” is what Dan Grossman mentioned at the start of the Programming Languages Coursera course and it was a profound statement for me.
The times when I have resisted learning new tools or getting used to new programming languages are the times I have atrophied.
The times when I threw away familiarity and explored new tools was when I learned and enjoyed.
Time and again, I have to make a commitment to throw familiarity away. That is what pushes me to learn to customize Emacs despite already having spent years mastering Vim and spent so much time using PyCharm, etc.
The flip side is that learning how to create a mobile app has always been a point of procrastination for me because it is all about learning new tools, new APIs, new IDE, etc.
- Always keep raw original data around.
You never know when you’ll need to reprocess it. It is always possible to reprocess but losing raw original data is a bad place to be. For example, if you’re auto-parsing some user input and it is not a selection that the user is choosing, then you’re probably better off storing the user input as-is and having a separate field where you store the result of your parsing the user input.
This habit is especially important to scale to a Lambda Architecture.
- Always use camel-case for data.
- Do logging-first development.
No matter how well-written or well-indented or well-formatted the code is, ultimately, the run-time behavior of the code is what determines the value of the compile-time code.
Always think about how to log the importants parts of the code which work based on time-sensitive data, so that your post-mortem on why something happened will be far easier.
For example, storing every API request and response to payment gateways was one of the best things I ever did when writing the ecommerce platform for Automatic. That clarified so many behaviors when investigating things after-the-fact, and it reiterates point 3 where it was easy to reprocess some statuses based on unexpected API responses, etc.
- First make it possible. Then make it beautiful. Then make it fast.
I’ve worked on tasks more efficiently and effectively whenever I have taken the time to get a quick “let’s get it working” version out there first, and then tweaking it constantly to get the software that the stakeholder wants.
- Queues are what makes things scalable.
Well, queues and asynchronicity are what makes things scalable.
Use queues wherever you can.
- Immutability is paramount.
It is what will keep your system sane. As @ghoseb says: “One day, we incurred a loss of a million Rupees at my company because of a bug that got triggered by my (apparently pure) code due to our usage of mutable datastructures in Common Lisp.”
Writing pure functions makes code far more predictable and easier to understand, and at the same time, keeps the prone-to-errors-because-of-data surface area of the code smaller.
A side-effect (sic) of considering immutability is that you learn to data all the things.