The Pragmatic Programmer: Part 3

Chapter 7. While You Are Coding

If you have a hunch about something, heed it. We keep on forgetting our lessons, but our subconscious brain remembers the patterns and communicates them as instincts. If the inner voice is not clear enough, distract yourself for a while or explain the problem to someone.

Instincts are simply a response to patterns packed into our subconscious mind.
So, let your instinct contribute to your performance.

Human beings have an innate habit of seeing a pattern where none exist. This can cause us to see patterns in dependencies and use them in a way they were never intended to be used. Assumptions that aren’t based on tested & verified facts are the bane of all projects.

Don’t code in the dark.
If you are not sure why it works, you won’t know why it fails.

Big(O) notation is a great way to get an estimate of your algorithm’s requirements but the key is to optimize only when required, even O(n²) may be acceptable if your loop runs only 1⁰² times. When algorithm speed optimization is not significant, prioritize readability.

“Premature optimization is the root of all evil.”
— Donald Knuth

Refactoring is changing the code’s internal structure without altering it’s external behavior and all projects need regular refactoring. Learning new facts, change in requirement, better understanding of the problem, removing duplicate code all qualify refactoring.

All code is tested, some by testsuite and others by customers. Thinking about tests enables us to think about various possible states of our program and ensure the behavior is as expected in all the states. It makes the code more reliable.

The first time a bug is found manually should be the last time the bug is found manually; next time it should be the testsuite.

We always have preconceptions about how our functions should work and we take these with us when we write tests. If the preconception is incorrect, so will be the tests. To avoid that, we let the machine pass random input and we only test for the properties of the output.

Small local, large CI: keep only a few property iterations locally and a lot in CI pipeline to ensure no bug slips the cracks while testing remains convenient.

Security through obscurity doesn’t work. Cryptography, Principle of least privileged, controlled and known attack surface area, input sanitation, secure defaults, regular security updates are just some of the low hanging fruits.

If the cost of breach is higher than the value obtained from the breach, only then you may consider your system to be safe.

Naming is important not just for the readability of the code but it also defines the world of the program. A good name keeps the code unambiguous and relevant to the problem domain.

8. Before the Project

No one knows exactly what they want, yet as developers we have to make it. So, we need to help the customer find what they need and make them explain their expectations clearly thought the means of communication, asking questions, flow charts & prototypes.

When faced with an impossible puzzle, write down all the constraints that are stopping you and evaluate if there is any way to remove them, search about how other people have dealt with the constraint. Take a step back and think about it before saying it can’t be done.

The team structure has an impact on the resulting code. Global teams show more modular products while teams that don’t communicate show single silo products. Pair programming enable people with different skills work together multiplying force and creating a shared understanding.

The Agile Manifesto wants a simple thing, flexibility. Not just in the product but the process of developing the code as well. Take what works and leave what doesn’t work but experiment and adjust frequently. Fail fast and learn from your mistakes.

9. Pragmatic Projects

Pragmatic teams are small(7–10) long-time members who trust and depend on each other. The team as a whole should not tolerate “broken windows”. Time spend on shared understanding in this team is critical and communication between all members should be frequent and unceremonious.

Do what works, not what is fashionable. Technology trends keep changing but experimentation and principles can reveal what is best for the team. The end goal is to deliver software faster, more reliably and with less effort, whatever helps in achieving the same is the correct way to do it.

Version Control, regression testing and full automation are three basic elements that all teams need regardless of their experience, techniques, scale or technology stack.

Users do not care about the software, they are trying to solve a business problem. Learning about the problem domain can help in understanding the problem. Delight users, don’t just deliver code.

An engineer at heart is a problem solver.

Sign your work, create product which will make you proud as a developer. Don’t enable bad actors to ruin the world, remember you might only be an employee but you are equally complicit if you cooperate.

“The greatest crimes in the world are not committed by people breaking the rules but by people following the rules.”
― Banksy

I hope you learned something new today. Good Luck with your skill development!

Stoic. Existentialist. Optimistically Nihilist. Snowdenist. Friendly. Confident. Perfectionist. Creative. Playful. Programmer. Philosopher.