I'm more of a thinker than a doer. Until presented with a deadline, I will only work on optimizing my approach instead of trying to actually solve the problem.
Recently I found myself falling into this trap again. I've been dabbling in a new programming language at work to help with the build system, and so while I don't need a ton of knowledge on how to read and write code in that language, it can help if you're at least somewhat familiar with the conventions and community around it. The problem was that I tried to dive in and learn all about the language's best practices and idiosyncrasies before I had even written a line a code in that language or for its build tool. My final change probably wasn't very pretty, but it only took me about an hour to track down the issue and patch it up. I had taken the entire rest of the day to even look for the problem.
This post is not about writing code. It's about getting things done imperfectly.
Don't be perfect the first time
No one is perfect the first time they try something, but that doesn't mean I don't try! I'll watch videos to make sure I'm cooking something right, I'll read blogs on how to make small adjustments to my text editor for maximum performance, and I'll read books on how to organize my life so I can squeeze that little bit extra bit of time out of my day. But I'll rarely follow through on those things, because the effort of being perfect is immense.
But I still can't quite learn my lesson. I'll never quite settle for "good enough" unless there's a deadline. I'd like to think that it's because I hold myself to a high standard, but it may be some bastardization of the old saying: if it's worth doing, it's worth doing well. I may have taken that to the extreme. Maybe it was from the saying I heard so much playing sports: practice doesn't make perfect, only perfect practice makes perfect. Regardless of where I get it from, it is not a trait I'm particularly proud of.
When I go back and revisit my initial attempts at something, I'm constantly blown away at how bad they were relative to my current position. My first omelette was just scrambled eggs, my first coding project was almost completely unreadable, and I took nearly an hour to iron my first dress shirt. But that doesn't mean I didn't spend hours practicing in my head for that first go.
Those hours should have been spent making more omelettes, or ironing more shirts. My first omelette stuck to my cast iron pan pretty badly because I didn't really know how hot the pan needed to be. It took me several rounds of laundry before I got even the slightest bit confident with an iron because I couldn't figure out how to manipulate the shirts on the board. And when I played baseball, the only pitch I threw that was any good was the one I could tell you the least about, even with tons of reading. I could tell you all the tips I've heard for throwing a good changeup, but none of them worked for me if I thought about it.
So, don't be perfect the first time. Don't even try to be perfect. Sure, you can go find someone who will help you learn faster. Sure, you should have some reference where you can look up if you're doing the right thing. But you need to do the thing before you can make progress.
You're not an expert yet
There's a famous graph showing how people perceive their expertise versus their actual expertise in an area, and I've found it shockingly accurate:
No matter how smart or talented or self-deprecating you are, you will fall for that bump in perceived knowledge.
I fell for it hard about 2 years out of school. With some help from my boss, I had been making great progress towards becoming an actual software engineer. I decided that I had conquered the mundane and needed to up my game: instead of just writing code, I should start reading about how all the best programmers in the world wrote code.
For the next 3 years, I couldn't stop reading up on coding best practices. Clean Code, Working Effectively with Legacy Code, Effective Java, the list goes on and on. Along the way I fell for several dogmatic traps. I remember the first time I read through Clean Code. The ideas blew me away, and I felt like I had to fix the multi-million line codebase to have it conform to such beautiful standards. At one point I took almost a full week to rewrite a single file (in my defense, it was a very large file), at which point I was approached by a colleague and asked to stop. I wasn't adding any value: I was changing perfectly readable and functional code to be inline with my new standard of cleanliness.
But, I was at least knowledgeable enough to help others. I started running reading groups for newer hires at the company to help them feel more comfortable talking about and thinking about code. It should have been more obvious to me at the time, but the people who I held in high regard for their code quality never even considered attending.
They were too busy honing their craft by actually writing code and interacting with other people who were also actually writing code. Talking about writing code isn't the same thing. I had learned to evaluate code, not write it.
You don't have to know why it works
This is something I've only recently come to appreciate: it's ok if you don't know how to help others. There's a saying to this effect: "Those who can, do. Those who can't, coach." While I've found this to generally not be true, there are exceptions and it's almost always people in the first category.
Some people get a head start at certain skills. Some kids are more coordinated than others and can kick a ball earlier. They get more time to practice, and they even started off better. Some of these people are so good that they never had to stop and think about what they were doing. I played baseball with a couple people like this in my life. Hitting a ball was obvious. Sure, some pitches were faster than others and some moved around some, but they just hit the ball when it was close to the plate. I could never do that, and so I thought about the game with a completely different perspective. They could rarely tell me why they did something because it was never even a thought for them.
When I go to such natural talents for advice, I rarely come away with anything I would expect. It will usually be an understanding of what it will be like when I get to that level ("I saw him using a lot of hotkeys on his computer, that might help him move around faster" or "I noticed he printed all his tax forms before starting, that might help keep things sane"). If you're one of these talents, it's ok that you can't vocalize why you do things. But the best and most talented people I've ever worked with also work hard to make sure they can help others understand.
At some point I had to just write some code. I'd taken all day learning about a new programming language and the build tools around it. I'd spent some time comparing their build system to the system we've standardized on at the rest of the company. But that's not a very good update for the daily standup meeting.
So I wrote some code. As I wrote something, I realized something else and wrote some more. In 10 minutes I had something almost working, in 15 I was pretty confident in what I was doing, and an hour later I had finished testing it and confirmed it was working.
None of my reading had been useful. But my code was understandable, my change was small and tested, and I had made sure to put comments in where I was unsure of things. Yes, I made some assumptions. I didn't try to find a general purpose solution. But I made it work without disrupting the system's maintanability.