Wednesday, August 10, 2011

97 Things Every Programmer Should Know

I just finished reading Oreilly's 97 Things Every Programmer Should Know. It was a very interesting compilations of essays from expert programmers. The book is very well done. They kept it short and to the point by having every essay to be no longer than two pages long. Here are some of my favorite:

Apply Functional Programming Principles - Edward Garson:
This caught my attention mostly because I am interested in learning Scala this year. Also, I'm currently working with stock trading and most of the principles resonate on what we do in an everyday basis at work. Additionally, some my Miami JUG colleges Luis Espinal and Jorge Fiallega, have emphasized on using these type of programming languages to leverage multicore.

Garson also mentioned that mastery of the functional programming paradigm can greatly improve the quality of the code you write in other contexts. If you deeply understand and apply the functional paradigm, you designs will exhibit a much degree of referential transparency.

Referential transparency is very desirable property: it implies that functions consistently yield the same results given the same input, irrespective of where and when they are invoked. That is, function evaluation depends less - ideally, not at all - on the side effects of mutable state.

The net result [using functional principles] is a design that typically has better responsibility allocation with more numerous, smaller functions that act on arguments passed into them, rather than referencing mutable members variables. there will be fewer defects, and furthermore they will often be simpler to debug, because it is easier to locate where a rogue value is introduced in these designs than to otherwise deduce the particular context that results in an erroneous assignment. This adds up to a much higher degree of referential transparency, and positively nothing will get these ideas as deeply into your bones as learning functional programming language.

The boy Scout Rule - by Robert C. Martin (Uncle Bob):
The boy scouts have a rule: "Always leave the campground cleaner than you found it". If you found a mess in the ground, you clean it regardless of who might have made it. I use a similar example, I have always compare bad code to a dirty parking lot. If you see a dirty parking lot, you are tempted to dirty it even more in contrast to a clean parking lot. Uncle Bob posts the question, "What if we all followed a similar rule in our code: Always check a module in cleaner than when you checked it out?". According to him, we would see the end of the relentless deterioration of our software systems. Instead, our systems would gradually get better and better as they evolved. We would see teams caring for the systems as a whole, rather than just individuals caring for their own small part.

Do Lots of Deliberate Practice - by Jon Jagger:
Delivery practice is not simply performing a task. If you ask yourself, "Why am I performing this task?" and your answer is, "To complete the task," then you're not doing delivery practice.

You do delivery practice to improve your ability to perform a task. It's about skill technique. Deliberate practice means repetition. It means performing the task with the aim of increasing your mastery of one of more aspects of the task.

Continuous Learning - by Clint Shank
I worked with a project lead that once told me, "I'm tired of constantly learning new languages, techniques, and tools". I thought to myself, "I think you are in the wrong line of work". The nature of our industry is that we need to keep learning. Although, this might be obvious, The moment that we stay stagnant we become stale. That is the reason why we have meet-ups and why we should always learn a new language. Here are some of the things that Shank mentions to keep us from being stagnant:
  • Read books, magazines, blogs. Twitter feeds and websites. If you want to go deeper into subject consider joining a mailing list or newsgroup.
  • If you really want to to get immersed in a technology, get hands on - write some code
  • Always try to work with a mentor, as being the top guy can hinder your education. Although you can learn from anybody, you can learn a whole lot more from someone smarter or more experienced than you. If you can't find a mentor, consider moving on.
  • Use virtual mentors. Find authors and developers on the web who you really like and read everything they write. Subscribe to their blogs.
  • Get to know the frameworks and libraries you use. Knowing how something works makes you know how to use it better. If they're open source, you're really in luck. Use the debugger to step through the code to see what's going on under the hood. You'll get to see code written and reviewed by someone really smart people.
  • Whenever you make a mistake, fix a bug, or run into a problem, try to really understand what happened. It's likely that someone else ran into the same problem and posted on the web. Google is really useful here.
  • A good way to learn something is to teach or speak about it. When people are going to listen to you and ask you questions, you'll get highly motivated to learn. Try a lunch-n-learn at work, a user group, or a local conference.
  • Join or start up a study group or a local user group for a language, technology, or discipline you are interested in.
  • Go to conferences. And if you can't go, many conferences put their talks online for free.
  • Long commute? Listen to podcast.
  • Ever run a static analysis tool over the codebase or look at the warnings of your IDE? Understand what they're reporting and why.
  • Follow the advise of the Pragmatic Programmers' and learn a new language every year. At least learn a new technology or tool. Branching out gives you new ideas you can use in your current technology stack.
  • Not everything you learn has to be about technology. Learn the domain you're working in so you can better understand the requirements and help solve the business problems. Learning how to be more productive - how to work better - is another good point.
  • Go back to school.

Deploy Early and Often - by Steve Berczuk
I really believe on Continuous Integration (CI), but I think I could do better. I have heard that in other big shops (Facebook, Googlde, and Netwflix) they have daily deployments. Here is Bercuk thoughts:
Debugging the deployment and installation process is put off until close to the end of a project. The installation/deployment process is the first step to having a reliable (or, at least easy debug) production environments. The deployment software is what the customer will use. By not ensuring that the deployment sets up the application correctly, you'll raise questions with your customers before they get to use your software throughly.

Starting your project with an installation process will give you time to evolve the process as you move through the product development cycle, and the chance to make changes to the application code to make the installation easier. Running and testing the installation process on a clean environment periodically also provides a check that you have not made assumptions in the code that rely on the development or test environments.

Don't be Afraid to Break Things - by Mike Lewis
This is something that I always encountered in many shops. Code that it's so bad that no one wants to touch it. Lewis' suggest not to be afraid of your code.
Who cares if something get temporarily broken while you move things around? A paralyzing fear of change is what got your project into this state to begin with. Investing the time to refactor will pay for itself several times over the life cycle of your project. An added benefit is that your team's experience dealing with the sick system makes you all experts in knowing how it should work. Apply this knowledge rather than resent it. Working on a system you hate is how anybody should have to spend his time.
Don't Repeat Yourself - by Steve Smith
Of all the principles of programming, Don't Repeat Yourself (DRY) is perhaps one of the most fundamental. the principal was formulated by Andy Hunt and Dave Thomas in The Pragmatic Programmer, and underlines many other well known software development best practices and design patterns. The developer who learns to recognize duplication, and understands how to eliminate it through appropriate practice and proper abstraction, can produce much cleaner code than one who continuously infects the application with unnecessary repetition.

Repetition in Logic Calls for Abstraction:
Repetition in logic can take many forms. Copy-and-paste if-then or switch case logic is among the easiest to detect and correct. Many design patterns have the explicit goals of reducing or eliminating duplication in logic within an application. If an object typically requires several things to happen before it can be used, this can be accomplished with an Abstract Factory or a Factory Method pattern. If an object has many possible variations in its behavior, these behaviors can be injected using the Strategy pattern rather than large if-then structures. In fact, the formulation of design patterns themselves is an attempt to reduce the duplication of effort required to solve common problems and discuss such solutions. In addition, DRY can be applied to structures, such as database schema, resulting in normalization.

A Matter of Principle:
Other software principles are also related to DRY. The Once and Only Once principle, which applies only to the functional behavior of code, can be thought of as a subset of DRY. The Open/Close Principle, which states that "software entities should be open for extension, but closed for modification," only works in practice when DRY is followed. Also the well know Single Responsibility, which requires that a class ahve "only one reason to change", relies on DRY.

How to Use a Bug Tracker - Matt Doar
I found many shops that do not have a good bug tracker. I really like Jira, and we are currently using it at work. But this is not enough, you specify a good "bug report". The lack of information can cause confusion or lack of credibility on the bug. For example, I have seen many bugs closed with "I can't replicate the bug", when in fact the bug was not well understood. This is what this essays is about.

A good bug report needs to convey three things:
  1. How to reproduce the bug, as precisely as possible, and how often this will make the bug appear.
  2. What should have happened, at least in your opinion
  3. What actually happened, or at least as much information as you have recorded

Improve Code by Removing It - Pete Goodliffe
There is direct correlation with lines of code and bugs. In here the practice of "less is more" is indeed useful. Pete writes about an anecdote regarding this exact problem.

I observed that the product was taking too long to execute certain tasks - simple tasks that should have been near instantaneous. This was because they were overimplemented - festooned with extra bells and whistles that were not required, but at the time had seemed like a good idea.

So I've simplified the code, improved the product performance, and reduced the level of global code entropy simply by removing the offending features from the codebase. Helpfully, my unit tests tell me that I haven't broken anything else during the operation.

Keep the Build Clean - Johannes Brodwall
I started a project for a client once and as soon as I started the server in prod there were a bunch of warning messages. When I asked the team leader about the warnings he replied: "those are OK warnings". We should keep the code as clean as possible. Like Broadwall says,
When I start a new project from scratch, there are no warnings , no clutter, no problems. But as the codebase grows, if I don't pay attention, the clutter, the cruft, the warnings, and the problems can start pilling up. When there's a lot of noise, it's much harder to find the warning that I really want to read among the hundreds of warnings I don't care about. To make warning useful again, I try to have a zero-tolerance policy for warnings from the build. Even if the warning isn't important, I deal with it. If it is not critical but still relevant, I fix it.
Again, the book is very well done and a quick read.

Thanks for reading the post.