In this post, I'd like to share some tips for productivity that I've already learned from working on Calypso.
I'll start with some basic tips:
- Try to keep your code maintainable. It's generally better to overengineer something maintainable than to underengineer something that's impossible to change once you find a bug.
- Don't overwhelm yourself. Start small, don't try to finish everything at once.
Now, here's the largest lesson I've learned from working on Calypso:
Don't get bogged down in the details. This is a HUGE issue for me. Basically, if you have a project with multiple interconnected parts, don't start by trying to finish one of those parts and then working on another part. Start small, and work on them individually. Get the whole system working with a subset of your expected input, before expanding to a full, working system.
When starting Calypso, I started with the lexer (as this is usually the first part you'd start with in a programming language). But I got bogged down in the details. I kept trying to finish the lexer before finishing the parser, and other parts of the implementation of the programming language.
This led to what I've had explained to me as "productive procrastination". Basically, I was so bogged down in the details that I felt that I had to get the lexer "perfect" before I could work on the next part in the implementation. So I started to work on unrelated parts that didn't require the lexer at all (or at least didn't require it to be "perfect"), and I did get some work done, but ultimately at the moment it hasn't been very helpful.
And I wasn't able to get the lexer perfect without finishing the language design. And then that got me bogged down in writing documentation (which I guess is ok, but...), and then that got me stuck writing syntax highlighting, which then led to writing a EBNF grammar for the language, which then got me back to language design. It was unchecked recursion and it went from productive procrastination to unproductive procrastination.
Recently, I decided to just stop. I commented out most of the code paths for the lexer, and just worked on the part that I hadn't worked on yet because I had failed to implement it a few times before and I was scared that I wasn't going to get it to work. But I did. I found a few bugs later, and that was fine. I got those sorted, out, then I started on a basic parser. Not the whole language, just simple arithmetic. Then I moved on to boolean operators and bitwise operators. Then I kept building and building until now I have a basic parser for expressions (barring things like lists and maps).
Sometimes you have to just stop yourself. You sometimes just need to say to yourself (possibly in a comment), "This code is purposefully incomplete. I'll come back to it later, once I'm done with the other parts and I have a better perspective on the design of the system overall".
Comment out code. Erase it, rewrite it if you need to! Then work on other parts in parallel. The only way to truly have a better perspective of the design of the overall system is not to design the whole thing in advance, it's to get stuck. You've probably heard the mantra, "If at first you do not succeed, try, try again." This is sometimes true, and this is a case. In fact, I don't want you to succeed at first. You shouldn't want that. 99% of the time, I've found that if something seems to work on the first try, it probably doesn't. And through this failure and suspicion, you can learn new things. You can find new perspectives and new ways to design things better and more correctly.
It's fine to fail. It's fine for something to not be perfect. And that's the most important thing to keep productivity. If you always succeed, there is no triumph in the end. Failure is a natural part of engineering software, and it's better that you have failure while you're developing your software, than while you're using your software in production and it's interconnected with a million other things that will break on one error, caused in code that you thought would work because it seemed to work on the first try. Failure is important, and while it's not always fun, it can help.
If you need to, take a break if you experience failure that you're not sure how to fix. Whether you're just pivoting from coding to another real-life activity, or just pivoting from one spot of the code to another, breaks are important. They can help you to get a new perspective on issues that you didn't have a good perspective on before.
Thanks for reading this. I hope this helps someone out there. Have a good morning/day/afternoon/evening/night/etc!