today is my birthday which means I've been coding for 25 years. A quarter century 😱
When I started, we didn't have a computer at home. An extra curricular class at school gave me 1 hour of programming per week. In Logo.
I don't remember which version we used but
repeat 4 [ fd 100 rt 90 ]
blew my 9 year old mind (it draws a square) and in that moment I knew that programming was my thing. One day I'll be a famous programmer like Bill Gates 💪
A lot has changed since then. Bill Gates isn't even a famous programmer anymore.
Here's 25 lessons I've learned about code. In no particular order.
PS: you can read and share this online
To go fast, go alone; to go far, go together.
Doesn't matter how good you are, there's a limit to how much you can do yourself. And a team can do all those things you're starting to think are boring.
You need tests. Automated or otherwise. Always start with "How will I know this works?" and verify in small increments.
But strict test driven development is a cult. You don't need to write an automated test and incur aeons of maintenance for every smol step.
Write tests. Not too many. Mostly integration.
Mocks are said to make your code more unit testable. Help you isolate different units to ensure you have reliable tests testing what you meant to test. None of that other code by those other developers.
Can't rely on that!
Guess what, your code does rely on that code and if it changes, you need to fix it. And with mocks you'll never know until you get a production bug.
The main reason you write unit tests is to ensure you call functions correctly, don't make typos, and get test failures when a function's API changes.
A static type system tells you all that on every keypress. Runs right in your IDE. Gives you red squiggly lines when something doesn't match.
Types are unit tests with 100% coverage, if you squint a little.
You do need [integration] tests for behaviors.
Occam's razor style – the simplest solution that solves the problem is best. When you start adding exception upon exception, it means your core solution is wrong. Reconsider.
You see this in large projects. Programmer finds a function that does what they need. But they don't quite understand how it works or why it exists.
They wrap the function in an abstraction of their own. A cozy little corner of the codebase they can understand.
Few months later, another programmer finds this function. Same thing happens.
Before you know it your codebase is full of abstractions of abstractions of abstractions and you have to spelunk through 10 layers of indirection to find a function that does something.
Stop that. Lean into code that exists.
Same with tools. You add workarounds when you don't understand the libraries and tools you're using.
Embrace what the authors envisioned. Do it their way. It's going to be fine, I promise.
College, online challenges, and interviews make you think that the work of programming is a glorious fight to the death with gnarly issues and never-before-seen problems.
That may be true in some fields for some people. The job for most is ferrying data from one side of a system to the other and back.
Nobody is coming to save you. If you want something, go get it. Don't ask, don't know, don't get.
Want bigger challenges? Ask. Want more interesting problems? Ask. Want more responsibility? Ask. Want fame in opensource? Make things. Want millions? Sell things. Want a blurb in every textbook? Solve hard problems. Want fame in industry? Achieve things.
Imagine how much you'd laugh at someone who builds their identity around the brand of hammer they use.
Programming languages are hammers.
The best way to improve as a programmer is to learn a new programming paradigm.
Once you understand the fundamentals and the problems you're solving, learning new languages and libraries and APIs is easy. They're all roughly the same.
Learning a new syntax is easy. Fluency comes harder.
You have to learn the common idioms and patterns of a community, their favorite tools, how they hold a language, what they use it for. You can't learn this from online exercises and tutorials.
You have to build something real.
The number of programmers about doubles every 5 years. The doubling is globally uneven. Right now India is growing much faster than USA or Europe.
With new programmers come new solutions to old problems. They don't know the old solutions.
You think you've found a novel solution to an exciting problem, but there's probably an old paper about it. At least about solving the same problem in a different context.
Modern computing started in the 1940's. The Von Neumann architecture was proposed in 1945. Our computers still use it today.
Computer networks are from the 60's, neural networks from the 70's, reliable databases from the 80's.
We've reinvented and rediscovered lots of tools since then, but fundamentally it's all the same. You might argue blockchain is at least trying to be new.
We use computer systems to solve hard organizational problems. Your code and system can't be simpler than the problem it's solving.
But try not to make it more complex than that.
Computers are dumb. If you can't even explain your solution to another person, how can you explain it to a computer?
It's the illusion of explanatory depth. You think you know how a pen works or what bicycle looks like until you try to explain the pen and draw the bike.
Many problems become simpler when you approach them a different way.
When your code is getting messy and you keep finding exceptions – try a new approach. You are likely using the wrong tool or the wrong level of computing strength.
You will never solve a contextual problem with a state machine well. And a graph problem is difficult to solve with hash tables.
Programming is not karate. You can't kata your way into being a good problem solver.
Bruce Lee fears the man who practiced the same kick 10,000 times, but problems fear the programmer who has 10,000 different tricks to try.
Coding would be easier without those pesky users and business requirements. And what's the point of that?
The fun comes with changing and evolving your code to meet new requirements. That's the art. Programming over time.
Want a clean codebase that makes you proud? Write code that encourages good practices and leads by example. You won't always be there to keep it nice.
Don't believe everything you read online. What works for a team of 10,000 may not work for your team of 10. And what works for a team of 10, makes no sense on a solo project of 1.
Think for yourself.
Always know why you're doing something. Engineering is about tradeoffs and if you can't tell why you're doing something, don't do it.
"Because <industry expert> said so" is not a reason. Neither is "The boss told me to". Ask them to explain the tradeoffs, helps you learn.
The corollary to that is to always explain your reasoning when helping others. Make a decision, then explain why. Next time they'll understand the reasoning and won't have to ask you.
Use verbs and phrases from the business side and never wonder what to name a function or variable ever again.
Here's how it works 👇
And get thoughtful letters 💌 on mindsets, tactics, and technical skills for your career. Real lessons from building production software. No bullshit.
"Man, love your simple writing! Yours is the only newsletter I open and only blog that I give a fuck to read & scroll till the end. And wow always take away lessons with me. Inspiring! And very relatable. 👌"
Ready to Stop copy pasting D3 examples and create data visualizations of your own? Learn how to build scalable dataviz components your whole team can understand with React for Data Visualization
Curious about Serverless and the modern backend? Check out Serverless Handbook, modern backend for the frontend engineer.
Ready to learn how it all fits together and build a modern webapp from scratch? Learn how to launch a webapp and make your first 💰 on the side with ServerlessReact.Dev
By the way, just in case no one has told you it yet today: I love and appreciate you for who you are ❤️