> To prove turing completness I think it would be better to show that script can emulate a turing machine
Seems fairly straight forward. The left part of the tape is the stack. The right part is the altstack. On top of the stack there's an additional integer for the current state. Then you define an iteration function that pops the current state and current tape value from the stack, examines it with a bunch of ifs and pushes the new state and new tape item to the appropriate stack. This iteration function is then unrolled N times.
> being able to support more than one iterative section would seem to require an inner unbounded repetition of code inside the outer block. Leading to at minimum highly unpractical code and possibly theoretical issues as well.
I think any C-like code can be rewritten to a state machine fairly efficiently. Nested loops would not lead to an exponential increase in unrolled code size.
This is how the "await" language feature found in many modern languages (C#, JavaScript, python) is implemented. This is a mechanical transformation that a compiler can perform. You can see it here:
https://sharplab.io/#v2:CYLg1APgAgTAjAWAFBQAwAIpwKwG5nJQDMmM6AwugN7Lp2YlYBsmAHJiwGIAUAlNbXpCAZgHsATum4BLAHYAXdNPQBedKlxL0AHnRwNSsGH40kQoQEgxkmQvQArVes2Pd+l0ZODzP+tOFSymAOOnqoXma+UUJQAJwcAHQAIgCmADYAhgCeMujB9rz4kdHmAL7e5hblxWUV1dVAA=
I put two nested loops in there and an if. The compiler rewrites it all away into switch+goto (which would become if plus an unrolled loop in Bitcoin script). The meat of this is in the MoveNext function which is compiler generated. MoveNext corresponds to what a single Bitcoin script would contain. There needs to be an outer loop that repeatedly calls MoveNext to move the state machine forward. In Bitcoin Script this can be done by unrolling or by a sequence of transactions.
Seems fairly straight forward. The left part of the tape is the stack. The right part is the altstack. On top of the stack there's an additional integer for the current state. Then you define an iteration function that pops the current state and current tape value from the stack, examines it with a bunch of ifs and pushes the new state and new tape item to the appropriate stack. This iteration function is then unrolled N times.
> being able to support more than one iterative section would seem to require an inner unbounded repetition of code inside the outer block. Leading to at minimum highly unpractical code and possibly theoretical issues as well.
I think any C-like code can be rewritten to a state machine fairly efficiently. Nested loops would not lead to an exponential increase in unrolled code size.
This is how the "await" language feature found in many modern languages (C#, JavaScript, python) is implemented. This is a mechanical transformation that a compiler can perform. You can see it here:
https://sharplab.io/#v2:CYLg1APgAgTAjAWAFBQAwAIpwKwG5nJQDMmM6AwugN7Lp2YlYBsmAHJiwGIAUAlNbXpCAZgHsATum4BLAHYAXdNPQBedKlxL0AHnRwNSsGH40kQoQEgxkmQvQArVes2Pd+l0ZODzP+tOFSymAOOnqoXma+UUJQAJwcAHQAIgCmADYAhgCeMujB9rz4kdHmAL7e5hblxWUV1dVAA=
I put two nested loops in there and an if. The compiler rewrites it all away into switch+goto (which would become if plus an unrolled loop in Bitcoin script). The meat of this is in the MoveNext function which is compiler generated. MoveNext corresponds to what a single Bitcoin script would contain. There needs to be an outer loop that repeatedly calls MoveNext to move the state machine forward. In Bitcoin Script this can be done by unrolling or by a sequence of transactions.