
Why does a Turing-complete type system make type checking undecidable? - luu
http://composition.al/blog/2017/02/27/why-does-a-turing-complete-type-system-make-type-checking-undecidable/
======
nightcracker
This always is an issue I take with people saying how certain technology is
impossible due to <insert proof reducing technology to halting problem>. Type
checking, code optimization, automatic proofs, etc. That's short-sighted.

As long as you reduce the power of your technology from "yes/no" to
"yes/no/don't know" you're good to go.

Some optimizations may be impossible to apply in general due to the halting
problem. But as long as you realize that the optimizer might return "I don't
know if I can apply this", you can conservatively apply the optimization in
the cases where the optimizer actually is sure.

Same for type checking. You can add a compiler warning: "Could not
automatically prove type correctness.". Done. Now you can automatically check
99% of the cases where there are no halting problem issues, and leave the
remaining 1% to the humans.

Don't let perfect be the enemy of the good.

~~~
BuuQu9hu
You have missed an important point: Your technology is not yes/no/dunno, but
yes/no/dunno/loop. Turing-completeness implies Rice's Theorem, which is
basically a fancy way of saying that you can't escape Turing's results just by
claiming that you're solving an "easier" problem as long as that problem is
still non-trivial.

I'm sorry that you think that our amazing farsighted glimpse of the edge of
computational infinity is "short-sighted", but in reality these upper bounds
are very useful for reminding us of the certain futility of certain tasks.

Moreover, I am also happy to point out that a problem not need be Turing-
complete to be computationally intractable even if decidable. Compilers
happily cheat on optimizations, register layout, etc. if it means not having
to run expensive algorithms. When a type-checker is accidentally quadratic-
time, people roll their eyes and fix it; when it's intentionally exponential-
time, people will avoid it entirely.

~~~
DannyBee
Except you can bound it, and you can escape it that way. IE "not gotten
anywhere after 30 iterations, so don't know".

Otherwise, you couldn't, for example, ever compute the tripcount for a loop
without risking running forever.

" Compilers happily cheat on optimizations, register layout, etc."

They don't cheat. They just make the problem easier at a cost of optimality.
Or, they discover they didn't need to solve the problem they thought they did.

A great example is register allocation. NP-complete to do graph coloring.

NP-complete to decide if a given graph admits a k-coloring for a given k
except for the cases k ∈ {0,1,2}.

NP-hard to compute the chromatic number (ie just figuring out the minimum
number of colors for a graph)

This was the state, right up until a number of people proved that, if you do
it on SSA form (a linear time transformation), you can optimally color it in
_linear time_. A small difference.

So, often, these upper bounds that seem "futile", maybe are not as futile as
one thinks.

~~~
theseoafs
> Except you can bound it, and you can escape it that way. IE "not gotten
> anywhere after 30 iterations, so don't know".

It should go without saying that this system is not Turing-complete anymore if
you bound the runtime.

~~~
oculusthrift
that is correct. the whole point is we can make practical real world tradeoffs
and break out of the shackles of theoretical constraints.

------
seveneightn9ne
In regards to the last paragraph. If the type system is turing complete, then
the type-correctness of the program _may_ be dependent on the output of an
arbitrary turing machine. Therefore, your type checker must be either
incomplete or its result must depend on the output of the arbitrary turing
machine.

------
shanemhansen
I feel like the question answers itself. Turing complete. Decidable. Pick one.

