Eugene's Blog

I can't believe it's blog!

What programmers do

Let me give you one more definition of what computer programmers do: they design, build, and maintain complex systems. In many cases computer programs are more complex than “Hello, world!” examples. Way more complex. I am talking about the systems

  • that have more branching possibilities than atoms in the universe.
  • that cannot be verified using any formal methods in any practical timeframe.
  • that cannot be tested with 100% code coverage in our lifetime.
  • that cannot be completely understood in all details by their creators.
  • that can handle real life requirements.

So what?

  1. Old programmers like telling anecdotes about clueless clients. Those programmers got old without understanding that they were dealing with complex systems. It is irrelevant whether their clients are really clueless or not. Do not expect that a client will give you a detailed specification that makes sense and is not self-contradicting. If she gives you such specs, expect to be over-constrained in your design, which will produce a system that is hard to use and difficult to maintain. Remember that a spec reflects a piece of the Real World, which is probably even more complex than the system the client asks you to design.
  2. Old programmers whine that nobody does design anymore like it is prescribed by smart books. Those guys forgot that they deal with complex systems. Do not spend your time polishing a detailed design — it will be wrong anyway. No, I don’t believe in “do not design” mantra of some gurus. If you go to a battle, you have to have a strategy, but you have to have some smarts and experience to go tactical when you started coding.
  3. “The system was coded to the spec.” Puh-lease! Do you want to meet the client’s spec literally or do you want to solve the client’s problem? Let me tell you right now that by choosing the former you will not make your client happy in the long run. Keep your eyes on the real problem when mapping your plans.
  4. “The system was coded according to the approved detailed spec.” Really? The client’s spec was bad, your general design is faulty by definition, and your detailed design will be a recipe for disaster. Detailed design should go hand in hand with coding. This is why it is better to have a small team of smart guys than a horde of mindless drones.
  5. “At work I support a system, which is a certifiable P.I.T.A. It was done by some bozos, which had their sadistic kicks writing a cryptic code.” — did you hear it lately? What does this tell you? The system was not designed to be maintainable. During charting and mapping your battle plans you should keep the complexity of your decisions down lowering the overall complexity. The system is complex already without your help. Simplicity helps while coding the system. It will help debugging it. It will help in maintenance.
  6. “Today I optimized my file reading code using bit shifts, and increments!” — please shoot anyone wasting time on premature optimizations. Do not optimize your code without solid reliable data obtained by profiling. If some piece of code doesn’t contribute to overall performance, optimize it to be as simple to understand as possible. Prefer short and concise code over “fast” code. (Incidentally this is why “scripted and interpreted” programs can outperform “compiled” programs by performance and/or overall costs — by being smart about optimization and design.)
  7. “When will I see the system working? — When it is done.” — did you hear conversations like that? You cannot do that with a complex system because there is a good chance it will never be perfected — during development you will discover more and more hidden complexities of the initial problem consequently sinking in a swamp of never-ending modifications. Do not code “till it is done”. “Release early, release often.” — this is how it should be. Ideally your program should work at any given time, while missing some unfinished features.
  8. Do not expect to debug your system in sessions. Start debugging it while designing: unit tests are your friends; assert all critical assumptions; design in the logging and reporting facilities. The latter can be reused by the client for tracking and monitoring.
  9. Do not flatter yourself that your system is bug-free because testers couldn’t find any more bugs and assert statements don’t show up in your logs — in many cases end users will use your system in completely unpredictable ways. Do not expect that the client will find all problems during an acceptance phase. You should be ready to go and fix the system as soon as problems arise. If you don’t want your clients to hate your guts, manage their expectations properly, and prepare them (and your team) for a maintenance mode. How? Repeat after me: keep the system simple.
  10. You didn’t expect that your design would be perfect. Do not expect you can create a perfect documentation. Plan for frequent updates especially in the beginning: create an electronic version of docs, and make it accessible for modifications by authorized users and developers. Wikis are perfect for that.

(Full disclosure: I am an “old” programmer myself.)

Yes, there are nice methodologies that cover all aspects of software development from a general project management to a naming of loop variables. Every year brings us new fashion of doing it. We learn new buzz-words, which will save the world. We are going top-down, and bottom-up with our code buddies watching over our shoulders while we apply patterns. And we are trying to be extremely agile at that. But in many cases we are way beyond direct applicability of all those “tried and proved” theories. They are not a dogma — try to understand them, and apply creatively to your projects at hand. It is true for this rant as well.

Now let’s recap:

  1. Do not expect a detailed specification.
  2. Do not spend your time polishing a detailed design.
  3. Keep your eyes on the real problem.
  4. Have a team of smart guys.
  5. Keep the complexity of your decisions down.
  6. Do not optimize your code without solid reliable data.
  7. Do not code “till it’s done”.
  8. Start debugging while designing.
  9. Do not flatter yourself that your system is bug-free.
  10. Do not expect to create a perfect documentation.

And stop whining!