I've read "what-is-turing-complete" and the wikipedia page, but I'm less interested in a formal proof than in the practical implications of requirements for being Turing Complete.
What I'm actually trying to decide is if the toy language I've just designed could be used as a general-purpose language. I know I can prove it is if I can write a Turing machine with it. But I don't want to go through that exercise until I'm fairly certain of success.
Is there a minimum set of features without which Turing Completeness is impossible? Is there a set of features which virtually guarantees completeness?
(My guess is that conditional branching and a readable/writeable memory store will get me most of the way there)
EDIT:
I think I've gone off on a tangent by saying "Turing Complete". I'm trying to guess with reasonable confidence that a newly invented language with a certain feature set (or alternately, a VM with a certain instruction set) would be able to compute anything worth computing. I know that proving you can build a Turing machine with it is one way, but not the only way.
What I was hoping for was a set of guidelines like: "if a language can do X,Y,and Z, it can probably do anything".
You need some form of dynamic allocation construct (malloc
ornew
or cons
will do) and either recursive functions or some other way of writing an infinite loop. If you have those and can do anything at all interesting, you're almost certainly Turing-complete.
The lambda calculus is equivalent in power to a Turing machine, and if you implement lambda calculus it is actually pretty fun writing lambda calculus programs. Way more fun than writing program for a Turing machine!
The only practical implication of Turing-completeness I'm aware of is that you can write programs that don't terminate. I've used a couple of special-purpose languages that guarantee termination and therefore are not Turing-complete. Sometimes it is useful to give up the extra expressive power in exchange for guaranteed termination.