Chess grandmasters, being able to look ten or even more moves ahead, was a myth more often than not, Maurice Ashley emphasizes in his inspiring TED talk. Rather than looking ahead, grandmasters ‘d think of simple end-game situations. In their minds, kind of working backwards, they’d try to simplify a chess game in its early phase to a promising end-game setting. Such settings involve fewer pieces and can be better grasped in the whole.

Coming up with a situation one wants to be in and step by step connecting it backwards to ones current situation, seems to be a technique not only be applicable to chess. Putting this idea to use in career planing or generally in planing ones future appears like an exciting thought. “If you can see the end-game, your youth won’t be wasted on you.”, Ashley says in conclusion, inspired by the famous quote “The youth is wasted on the young.”.

Likewise computer science is a domain were this technique works perfectly. Especially in programming it’s often easier to imagine the program is already working and developing parts of the software based on this assumption. So instead of starting with nothing and trying to come up with a step by step description of the program, we start with the assumption that the program already does what it should and work our way backwards. This approach often leads to declarative or recursive programs. When programming in functional or logical languages like Haskell or Prolog this is my favorite strategy of thinking about problems.

Let’s look at a simple example. Say we want to program a function which calculates the factorial of a number. The factorial of 5, for example, is denoted as “5!” and means the product of all natural numbers till and including 5. So 5! is the same 5*4*3*2*1 = 120. A standard function definition in a procedural language would not be difficult, involving the use of only one loop. But let’s use our “backwards strategy”.

1 2 3 |
int factorial(int i) { // define function here } |

Let’s assume or function “factorial” is already working. How can we generate a result for our function argument “i”. The idea is to use our assumption, that the function is already working, to get the factorial of “i-1”. If we have done that, the only thing left for getting the factorial of “i” is to multiply with “i”.

1 2 3 |
int factorial(int i) { return i * factorial(i-1); } |

But wait, factorials are not defined for negative numbers, so if we’d pass “0” into our function, our program would try to get the factorial of “-1”. To prevent that we add the base case “0” as a special rule (mathematically “0!” is defined as “1”). With doing so, we have retrieved a terminating and working program.

1 2 3 4 |
int factorial(int i) { if (i == 0) return 1; return i * factorial(i-1); } |