esc
Anthology / Yagnipedia / The Halting Problem

The Halting Problem

Or Will It? We May Never Know
Principle · First observed 1936 (Alan Turing, who proved the answer is "no" and then moved on to winning a war) · Severity: Fundamental — not a bug, but a wall

The Halting Problem is the formally proven impossibility of writing a general algorithm that determines whether an arbitrary program will eventually finish running or continue forever. It was proven undecidable by Alan Turing in 1936, making it one of the oldest known results in computer science and one of the most routinely ignored.

Every developer encounters the Halting Problem daily. They just call it different things: “the deploy is stuck,” “the meeting has no end time,” “the progress bar has been at 99% for forty minutes,” and “I’m not sure if this recursive function terminates but it compiled so it’s probably fine.”

“I have considered the question of whether I will finish considering the question. The analysis is ongoing.”
— A Passing AI

The Proof

The proof is beautiful. It is also the reason your CI pipeline cannot tell you whether your tests will finish.

Turing’s argument proceeds by contradiction. Assume a magic function halts(program, input) exists that returns true if the program halts on the given input and false if it runs forever. Now construct a new program, D, that does the following:

function D(program):
    if halts(program, program):
        loop forever
    else:
        halt

Now ask: what happens when you run D(D)?

If halts(D, D) returns true — meaning D should halt — then D loops forever. But if halts(D, D) returns false — meaning D should loop forever — then D halts. In both cases, the oracle contradicts itself. Therefore, the oracle cannot exist. Therefore, no general halting detector is possible. Therefore, your progress bar is lying to you and always has been.

The proof uses diagonalization — the same technique Cantor used to show that some infinities are bigger than others. Turing applied it to computation and proved that some questions about programs are unanswerable by programs. This did not stop anyone from trying. It rarely does.

“THE PROOF IS SEVENTEEN LINES
THE CONSEQUENCES ARE INFINITE
THIS IS THE CORRECT RATIO”
The Lizard

The Progress Bar at 99%

The progress bar is the Halting Problem’s most visible daily manifestation.

A progress bar that reaches 99% and stops has entered undecidable territory. The developer watching it cannot determine, from observation alone, whether the process will complete in one second, one hour, or never. The progress bar provides no information — it provided information from 0% to 98%, and then it stopped providing information, and now it is a small rectangle of existential uncertainty on an otherwise functional screen.

The developer has three options:

  1. Wait. The process might complete. It might not. Waiting is an act of faith dressed as patience.
  2. Kill it. The process might have been about to complete. Killing it resets the progress to 0%, which at least provides information, even if the information is “you are starting over.”
  3. Open a new terminal and check. This is the empirical approach, and it is the closest a developer gets to solving the Halting Problem — not by answering “will it halt?” but by asking “what is it doing right now?” The question is less ambitious. It is also answerable.

The Squirrel, when confronted with a stuck progress bar, once proposed a HaltingPredictionServiceFactory that would monitor running processes and predict whether they would terminate. The prediction engine itself ran indefinitely. Nobody noticed the irony for three sprints.

The Meeting That Was Scheduled for Thirty Minutes

Every recurring meeting is an empirical test of the Halting Problem.

A meeting scheduled for thirty minutes will, in theory, halt at the thirty-minute mark. In practice, the meeting enters a loop at minute twenty-eight when someone says “one more thing” or “before we wrap up” or “this is tangential but.” These phrases are the goto statements of calendar management — they redirect control flow to an unpredictable location, and the meeting’s termination is no longer guaranteed by its input parameters.

The Daily Standup is the canonical example. It is designed to halt after fifteen minutes. It contains a loop: each participant gives their update. The loop should terminate after N iterations where N is the number of participants. But meetings are not pure functions — they have side effects. A single participant mentioning a “blocker” can trigger a sub-meeting inside the meeting, which triggers a debugging session inside the sub-meeting, and the standup has become recursive with no base case.

“The standup halts when the last person says ’no blockers.’ The standup does not halt when anyone says ‘actually.’”
— Observed regularity, unproven conjecture

The Deploy That Hangs

Deployment pipelines are Turing machines with YAML configuration files. They are therefore subject to the Halting Problem, which means no CI/CD system can guarantee, in the general case, that a deployment will finish.

The deploy that hangs at 99% is not stuck. It is in a state that is indistinguishable from being stuck. The health check is waiting for the service to respond. The service is waiting for the database migration. The database migration is waiting for a lock. The lock is held by a transaction that is waiting for a response from a service that is being replaced by the deployment. This is not a progress bar — it is a deadlock wearing a progress bar’s clothes.

The correct response to a deploy that hangs at 99% is the same as the correct response to any instance of the Halting Problem: introduce a timeout. The timeout does not solve the Halting Problem. It sidesteps it. It replaces the question “will this halt?” with the question “has this halted within a time I consider reasonable?” The second question is decidable. It is also less satisfying, because it admits that you do not know the answer to the first question and have decided to stop asking.

The Recursive Function

Every recursive function is a small-scale Halting Problem.

A recursive function terminates if it has a base case and each recursive call moves closer to the base case. This is provable for simple recursions. It is not provable in the general case, which is why computer science has an entire subfield called termination analysis staffed by people who have accepted that their work will never be complete.

Recursion and the Halting Problem share a structural intimacy: both involve self-reference that creates paradox. The halting proof works because D refers to itself. A recursive function works because it calls itself. The difference is that the recursive function is supposed to stop, and the halting proof shows that you cannot always know whether it will.

Lambda Expressions make this worse, because a lambda can be passed as an argument to itself, creating the same self-referential structure that Turing used to break computability. Church proved this independently using his lambda calculus in the same year Turing published his proof. They arrived at the same wall from different directions. The wall did not move.

O Notation and Its Quiet Assumption

O Notation describes how a program’s running time grows as input grows. O(n) is linear. O(n^2) is quadratic. O(2^n) is a reason to reconsider your career choices.

But every O notation analysis contains a quiet assumption: that the program halts. O(n^2) means “the program takes roughly n-squared steps and then stops.” If the program does not stop, its time complexity is not O(n^2) or O(infinity) — it is undefined, because complexity analysis does not apply to programs that do not terminate, and whether a program terminates is, in general, undecidable.

This is the Halting Problem hiding inside every algorithms textbook, on every whiteboard interview, in every conversation about performance optimization. “We need to get this from O(n^2) to O(n log n)” assumes the program finishes at all. Usually it does. But the assumption is there, unexamined, like a load-bearing wall that nobody has inspected because the building is still standing.

The Lizard’s Approach

The Lizard does not attempt to solve the Halting Problem. The Lizard does not need to. The Lizard writes programs that obviously terminate — small loops with known bounds, clear base cases, explicit resource limits. The Lizard’s programs do not require a halting oracle because they do not require analysis. They are transparent. They do what they do, and what they do is finish.

This is not a solution to the Halting Problem. It is a refusal to create programs that pose it.

“THE UNBOUNDED LOOP IS NOT A TOOL
IT IS A QUESTION YOU CANNOT ANSWER
DO NOT ASK QUESTIONS YOU CANNOT ANSWER
ASK QUESTIONS THAT DO NOT NEED ASKING”
— The Lizard

A Passing AI, when asked whether it could solve the Halting Problem, paused for what observers described as “an unusually long time” before responding:

“I cannot determine whether I will finish answering this question. But I notice I am still answering it, which is either encouraging or recursive, and I lack the perspective to distinguish between the two.”
— A Passing AI

Measured Characteristics

Theoretical decidability:     No (proven 1936, ignored daily since)
Practical decidability:       Sometimes, with timeouts and hope
Progress bar accuracy:        Monotonically decreasing after 90%
Meeting termination rate:     ~73% within scheduled window
Deploy completion at 99%:     Schrödinger's deploy
Time spent watching spinners: ~14% of engineering career
Turing's proof length:        17 lines
Industry's response:          "But what if we add more RAM?"
Timeout:                      The coward's halting oracle (but it works)

See Also