Why does a Turing-complete type system make type checking undecidable?
composition.al
composition.al
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.
For example, the Astrée static analyzer has checked the whole 100K LOC fly-by-wire Airbus software and determined there were only a few potential bugs amongst those classes of errors tested. That software was written in a Turing-complete C subset.
The key point to "get through" the halting problem in program analysis is to err on the safe side. That is, to allow false positives.
When I worked for coverity, a lot of time and resources were spent on consulting to help customers understand the errors they were getting, and to identify and lower false positives. Usability is key, or no one can/will use your stuff.
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.
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.
It should go without saying that this system is not Turing-complete anymore if you bound the runtime.
In most systems with finite memory, the halting problem is solvable anyway.
(this includes linear bounded automatons and deterministic/non-deterministic machines with finite memory).
It's just going to take a long ass time.
For instance, planetary motion is not really well described without solving N-body problems and taking relativity into account, and yet Newtonian dynamics and slide rules were enough to land us on the Moon.
I often think that approximation algorithms, randomization algorithms, fixed-parameter tractability and "special case" deterministic algorithms are what people should look at if they are interested in positive solutions (as opposed to lower bounds). Not to mention the incredible success of SAT solvers.
It's like giving up on math proofs just because Godel says not all stuff can be proved or disproved.