Let’s repeat what we know one more time.

We know that actOutOpposite(code) does the exact opposite of what code(code) does.

We want to know what happens when we run actOutOpposite(actOutOpposite) .

Well, if we pass in actOutOpposite as code , it means that actOutOpposite(actOutOpposite) does the exact opposite of what actOutOpposite(actOutOpposite) does?

Oh oh.

Looks like we found a corner case for which, no matter what Callback Cat says happens (the code terminates or doesn’t), the opposite will happen.

The Halting Problem

Callback Cat’s claim would actually be a solution to a famous problem in Computer Science called the halting problem.

In computability theory, the halting problem is the problem of determining, from a description of an arbitrary computer program and an input, whether the program will finish running, or continue to run forever

One of the main reasons the halting problem is as famous as it is is because it is one of the first problems that were shown to be impossible to solve.

Note: The approach that we‘ve used above to show that callbackCatsClaim does not work is called a proof by contradiction, and is a common way to demonstrate that the halting problem cannot be solved.

The halting problem is part of a group of unsolvable problems in CS that are called “undecidable”. An undecidable problem is one for which it is proved to be impossible to construct an algorithm that always leads to a correct yes-or-no answer. In other words, sometimes we just don’t know the answer.

This means that, although callbackCatsClaim has a perfectly well-defined, deterministic value for every individual program and input, we can't write a program that can decide it for every program/input pair.

Why does it matter?

The discovery of the halting problem was revolutionary because it showed us that some problems just cannot be solved. Some solutions are impossible to generalize for all scenarios.

This is important because the halting problem isn’t the only one of its kind.

Equipped with the realization that undecidable problems exist, you can learn how to recognize them and save yourself from going on a wild goose chase, wasting time or resources.

In fact, undecidable problems are all around us.

Let’s take basketball for instance.

Could you tell me, with absolute certainty, if the Golden State Warriors will never win the NBA title again?

If you think they definitely will, can you write a program to tell me exactly after how many seasons?

Perhaps you could write a program that takes in any possible NBA roster as its arguments, and outputs which year that roster would win the NBA title?

All of these problems are just the halting problem in disguise.

In general, if a problem you’re dealing with requires you to know, generalized across an infinite set of cases, when something specific will happen, or if it will ever happen, you’re likely dealing with the halting problem.

No matter how much computing resources we poses, some problems will never be solvable in a generalized manner. Some computer programs will always have an edge case that won’t be covered.

Writing a program to decide if a given player in a game you’re building will ever reach 100,000 points? The halting problem.

Writing a program to decide when will any given UI spinner stop spinning? The halting problem.

Writing a program to decide if a compiler always produces the fastest resulting code from a given source code? The halting problem.

Lucky for us though, an approximate solution is many times more than enough in practice.

If you knew the exact roster of an NBA team, their age, physique, etc, you could probably arrive at a good estimation of when they would win the title.

In fact, we can even solve the halting problem for many cases.

One common, approximate, and practically efficient solution to the halting problem is to just use a timeout. If a program you’re testing doesn’t terminate within some (generous) time limit, then it’s ok to assume it likely never will.

Pizza time

It is true that, with enough effort and time, most problems can be solved.

Most of the time, if we try hard enough, we’ll eventually get to a solution.

Yet for those few times where that’s impossible, the most effective solution is to recognize that there isn’t one.

Recognizing when a problem is the halting problem in disguise will save time and resources. Sometimes the best program is the one that is fast, efficient, but fails in some corner cases.

Well, well. Looks like Callback Cat got a little ahead of themselves.

“Ok my friend, Callback Cat admits defeat. Time for some well-deserved pizza.”