Pages

Saturday, December 28, 2013

Assertive Programming

 If you believe that something can never happen in your code, use assertions to ensure that. Never go with assumptions only.

"This code won't be used 30 years from now, so two-digit dates are fine."
"This application will never be used abroad, so why internationalize it?"

Always avoid this kind of self-deception.

In C and C++, we have assert macros which check a boolean condition. Here is an example:

void writeString(char *string) {
   assert(string != NULL);
   ...
}

This assert statement checks for a null string before executing the code inside the method. The execution stops when it encounters a null string.

While using assertions, make sure that they don’t make any side effects. The conditions passed to assertions may sometimes create side effects. Never put code that has to be executed as a part of the program into an assert statement.

Asserts shouldn’t be used for real error handling. Assertions check for things that should never happen.

Leave Assertions Turned On

Some people have a misunderstanding that assertions will become overhead after testing and deploying to production, and hence they should be turned off in production. The real problems start in production, not while developing or testing. Always leave the assertions turned on.

Turning off assertions when you deliver a program to production is like crossing a high wire without a net because you once made it across in practice. There's dramatic value, but it's hard to get life insurance.



- summary of Assertive Programming, from The Pragmatic Programmer: from Journeyman to Master

Thursday, December 26, 2013

Dead Programs Tell No Lies

Sometimes other people can easily find what’s not right with us, even before we realize it. It is true with other people’s code too. If something goes wrong in our code, sometimes it is a library routine that catches it first. In normal case, it is easy to fall into the "it can't happen" mentality.

But pragmatic programmers always code defensively. We always look for rogue pointers in other parts of the program. We always check that the correct versions of shared libraries were actually loaded.

All errors give you information. You could convince yourself that the error can't happen, and choose to ignore it. Instead, Pragmatic Programmers tell themselves that if there is an error, something very, very bad has happened.

Crash, Don’t Trash

It is always better to crash immediately after finding a problem than going wrong indefinitely. One example for this is Java. It throws an exception when something wrong happens. If that exception is not handled properly, the execution stops. In languages like C, which doesn’t not support exceptions, we can make use of macros.

When our code discovers that something that was supposed to be impossible happened, our program is no longer viable. Terminate it as soon as possible. A dead program normally does a lot less damage than a crippled one.

- summary of Dead Programs Tell No Lies, from The Pragmatic Programmer: from Journeyman to Master

Wednesday, December 18, 2013

Design By Contract (Part 1)

A contract defines the rights and responsibilities of a person, as well as those of the other party. Each party respects their commitments and everyone benefits. We can use the same concept to make software modules interact.

The concept of Design by Contract was developed by Bertrand Meyer, for the language Eiffel.

Every methods in a software system does something. Before doing that, the routine may have some expectations. Meyer describes these expectations and claims as follows:

  • Preconditions - The requirements for the routine. It defines what must be true for the routine to be called.
  • Postconditions - What the routine guaranteed to do. This defines the state of the world when the routine finishes its tasks
  • Class invariants - A class ensures that this condition is always true from the perspective of a caller. By the time the routine exits and control returns to the caller, the invariant must be true.



summary of Design by Contractfrom The Pragmatic Programmer: from Journeyman to Master

Wednesday, December 11, 2013

Pragmatic Paranoia

While driving, everyone personally thinks that they are the only good driver on Earth. We find all other drivers violating the rules. Then we start driving defensively. We look out for trouble before it happens. We always expect the unexpected.

The situation is similar in software world. We constantly encounter code written by other programmers - code that might not live up to our high standards. We check for errors or bad data.

But pragmatic programmers are always a step ahead.

They don't trust themselves, either!

No one writes perfect code. There is nothing called perfect software. We all should accept this fact. Pragmatic programmers code in defenses against their own mistakes.

Here, we’ll discuss about the defensive measures we take while coding.


summary of Pragmatic Paranoia (introduction)from The Pragmatic Programmer: from Journeyman to Master

Tuesday, December 10, 2013

The Art of Simplicity (Part 1)

It was for the first time, that we were visiting Technopark, Trivandrum. That’s one of the main reasons as to why we reached a little late. Dr. Venkat Subramaniam had already started delivering his keynote on The Art of Simplicity. Here, I am extracting some key points from it (I am directly jumping into the topic since I missed the first few minutes of the session!)...

Simplicity.. Being simple is always distraction-free. One example that we see and use in our day to day life is Google. Imagine, we are in the middle of a serious coding session. Suddenly, some confusion strikes our mind and we decide search for a better implementation or syntax. In the World of internet, there are a lot of things that can distract us. They tempt us to navigate away from our real goal, thereby, wasting a good share of our productive time.

This is where Google comes to help us. In the home page of Google, there is nothing to deviate us from our real intention. Just search, get what you want and leave! The real courage lies in developing such simple and elegant systems rather than complicating it with detailed designs or images.

Simple fails less. If at all it fails, it is always easy to find out the problem and cure it. Simple is always easy to understand.

Simple is always mutable. We neither have to change much, nor worry about anything else before changing it.

Here is a famous quote by Richard Feynman, an American theoretical physicist:

If you can't explain something to a first year student, then you haven't really understood it.

(to be continued...)



Thanks to +Vaishnavi M K and +Arun Prakash for your suggestions and proofreading.. :-)

Monday, December 09, 2013

Active Code Generators

Passive generators are used for convenience. But active generators are required if we want to follow the DRY principle. An active generator takes a single piece of information in one format and converts it into different formats. The generated code is disposable. The code is generated as needed by the generator. Whenever we find ourself trying to get two disparate environments to work together, we should consider using active code generators.

Active generators can be used in situations when we have multiple programming languages in a single application. In order to communicate, each code base will need some information in common, like data structures, message formats etc. Sometimes, we can parse the information out of the source files of one language and use it to generate code in a second language.

Code generators need not be complex. Keep the input format simple, and the code generator becomes simple.

Code generators need not generate code.  

It can be used to generate any text that is required in our project.


summary of Code Generatorsfrom The Pragmatic Programmer: from Journeyman to Master

Friday, December 06, 2013

Passive Code Generators

Passive code generators saves typing. They generate a given output from a set of inputs. The generated output is an independant source file. The origin of the file will be forgotten.

Passive code generators can be used for:

Creating new source files: While creating a new source file, some editors automatically add basic code, comments and other auto generated blocks to the file. This is done by using a passive code generator. They can be also used for generating source code control directives or copyright notices.

Performing conversions among programming languages: Passive code generators can be used for performing one time conversion of code from one programming language to another. The conversion need not be 100% accurate. We get to choose how much effort you put into the generator, compared with the energy we spend fixing up its output.

Producing lookup tables and other resources: Many of the earlier graphics systems were using precomputed tables, instead of calculating the trigonometric values, for sine and cosine values. These lookup tables were generated using passive code generators.


summary of Code Generatorsfrom The Pragmatic Programmer: from Journeyman to Master

Thursday, December 05, 2013

Code Generators

A code generator is a set of code that generates another code. This is used when the same code has to be used in different places (where we want to have the same functionality) with different contexts. This helps to avoid repetitive typing and once built, code generators can be used throughout the life of the project at virtually no cost.

There are two main types of code generators:

  1. Passive Code Generators - They run once and produce result. The result is free from the generator used. 
  2. Active Code Generators - They are used each time when a result is required. The result is a throw-away, which can be always reproduced.


- summary of Code Generatorsfrom The Pragmatic Programmer: from Journeyman to Master

Tuesday, December 03, 2013

Debugging (Part 4)

The Elements of Surprise

When something goes wrong, the amount of surprise we feel is directly proportional to the amount of faith we have in our code. This is the main reason that makes us think that there is something wrong with the library or the third party code we use. We must realize that one of our assumptions might have gone wrong. Prove it, if it is not, by checking all the boundary conditions.

Don't Assume It—Prove It

When we come across a surprising bug, take some time to think why it wasn't caught earlier. Merely fixing the code may cause the bug to happen again. Always check whether there are any other areas of code susceptible to the same bug. If yes, find and fix them. If bug fixing takes a longer time, ask ourselves the question: why?  If the bug occurred due to somebody’s wrong assumption, discuss the same with the whole team. If one person assumes incorrectly, there is a greater chance that others may also go wrong.

Do all this, and hopefully you won't be surprised next time.

Debugging Checklist
  • Is the problem being reported a direct result of the underlying bug, or merely a symptom?
  • Is the bug really in the compiler? Is it in the OS? Or is it in your code?
  • If you explained this problem in detail to a coworker, what would you say?
  • If the suspect code passes its unit tests, are the tests complete enough? What happens if you run the unit test with this data?
  • Do the conditions that caused this bug exist anywhere else in the system?

summary of Debugging, from The Pragmatic Programmer: from Journeyman to Master

Monday, December 02, 2013

Agile Kerala 2013: An Awesome Experience

It's only once in a while, we meet people who inspire us. In the last three days, I could meet many of them. We were at Technopark, Trivandrum to attend Agile Kerala 2013. It was the first ever Agile and Lean software development conference in Kerala. Truly speaking, I registered for the conference only because I would be able to visit Kerala and meet some of my friends. Learning was only my second priority.

But after going there, everything changed. It was an unexpected and awesome experience, I must say! Main talks were delivered by Venkat Subramaniam, an Agile Developer and Naresh Jain, Tech Startup Founder & Agile Coach. Both of them, and all other speakers were really good and gave us a memorable experience to cherish. The talks helped all three of us to have a better insight into Agile. 

We were not learning agile, but were experiencing it live!

The best among them was the live pair programming session by Naresh & Venkat. Unlike all other sessions, it was truly unplanned. This helped everybody, even for those who were new to pair programming and Test Driven Development (TDD), to understand the real power and use of these practices. They showed us how TDD helps us to detect and correct problems long before compiling the code...

There are more things to tell than a single post can contain. I'll be posting about the sessions soon.

Thanks to Vinod Purushothaman and Manoj Vadakkan for organizing such a beautiful event. Thanks to all other speakers...

I am quite sure that +Arun Prakash and +Vaishnavi M K experienced the same.. Happy to have you both there...  :-) 

And this is my first personal post other than the summaries. Please do comment and criticize.. I always love to hear feedbacks from you...


All good, all the time,

Yedhu Krishnan

Debugging (Part 3)

Let’s look at some commonly used debugging strategies:

Visualize Your Data

The best way to understand what a code is doing or what a code is going to do, is to look at the data it is operating on. The simplest way is to use ‘variable name = value’ approach. But it will much more helpful if we use some debugging tools which help us to visualize data. There are debuggers that represent our data as 3D diagrams. Even if our debugger has limited capabilities for visualizing data, don’t go panic! We can do it by ourselves by using hand, pen and paper or by using some external tools.

Tracing

Debuggers allow us to check the current state of the program. But sometimes, we need more than that. What if we need to check the state of the program or a data structure for over a period of time? That’s when we use tracing codes.

Tracers are simple, primitive statements that we write into our code or file. It could be messages like ‘reached here’ or ‘value of x = 2’. Even though it looks simpler, it is particularly effective and important at many places.

Tracing statements can be used to "drill down" into the code.

Rubber Ducking

One of the simplest ways to find a cause for the problem is to explain the same to somebody. The other person may not have to do anything. Just listen and nod (like a rubber duck bobbing up and down in a bathtub). While explaining things step by step, we will be able to find the cause by ourself.

Verbalizing some of the assumptions we took always helps us to get new insights about the problem.

Process of Elimination

We might be working on a mixture of application code, written by us, written by others, third party products like database etc and the platform environment like OS and system libraries. It is possible that there exists a bug in OS, compiler or library. But that should not be our first thought when a problem is detected. It could be the code under development. Sometimes it happens because the application code is incorrectly calling the library. Even if the problem does lie with a third party, we'll still have to eliminate our code before submitting the bug report.

Eliminate the correct parts one by one and narrow down the domain. Finally we will be able to track down the real culprit.


summary of Debugging, from The Pragmatic Programmer: from Journeyman to Master