In comp.theory Dude <punditster@gmail.com> wrote:
By banning unbounded loops and wild recursion, you ensure that every
valid program in the language is guaranteed to finish
No. Besides, unbounded loops (such as event loops) are necessary.
Recursion is, too, if you want to program things like tree structures.
On 2026-09-25 12:01, Alan Mackenzie wrote:
In comp.theory Dude <punditster@gmail.com> wrote:
By banning unbounded loops and wild recursion, you ensure that every
valid program in the language is guaranteed to finish
No. Besides, unbounded loops (such as event loops) are necessary. Recursion is, too, if you want to program things like tree structures.
Note that recursion isn't "necessary" to program [operations on]
tree structures. It just makes the algorithms appear simpler and
clearer, thus recursion is a sensible technique to implement
application cases like those.
WRT Dude's statement it should be mentioned that a recursive algorithm
can be transformed to an iterative one, so if iterative algorithms
would have the property to be _decidable_ to finish - actually, they
are not - we could also say the same for a recursive one.
Janis--
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
On 2026-09-25 12:01, Alan Mackenzie wrote:
In comp.theory Dude <punditster@gmail.com> wrote:
By banning unbounded loops and wild recursion, you ensure that every
valid program in the language is guaranteed to finish
No. Besides, unbounded loops (such as event loops) are necessary.
Recursion is, too, if you want to program things like tree structures.
Note that recursion isn't "necessary" to program [operations on]
tree structures. It just makes the algorithms appear simpler and
clearer, thus recursion is a sensible technique to implement
application cases like those.
Some things you need to do on trees need either explicit recursion, or "simulated recursion", where static arrays are used to hold intermediate values of variables. This approach limits the depth of a tree, possibly
more so than the size of the stack when using explicit recursion. We
might just be arguing about the meaning of words here.
WRT Dude's statement it should be mentioned that a recursive algorithm
can be transformed to an iterative one, so if iterative algorithms
would have the property to be _decidable_ to finish - actually, they
are not - we could also say the same for a recursive one.
Recursion can often be programmed iteratively in practice. In theory,
there are recursively defined functions which grow too quickly with increasing argument to be definable (or programmable) without recursion.
[ Followup-To: set ]
In comp.theory Dude <punditster@gmail.com> wrote:
[ .... ]
You can use restricted programming languages or subsets (such as MISRA
C, SPARK, or Rocq) that are not fully Turing-complete.
MISRA C is turing-complete, just as C is. I don't know about the
others, but it is likely they are turing-complete too.
MISRA C is a subset of C which supposedly reduces error possibilities,
at the expense of bloat. As far as I'm aware, no studies have been done which show that MISRA C is in fact better than full C, for any value of "better". It is a religion in programming for automotive applications,
no more to be questioned than the Lord's Prayer in a Christian church.
By banning unbounded loops and wild recursion, you ensure that every
valid program in the language is guaranteed to finish
No. Besides, unbounded loops (such as event loops) are necessary.
Recursion is, too, if you want to program things like tree structures.
On 2026-09-25 15:48, Alan Mackenzie wrote:
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
WRT Dude's statement it should be mentioned that a recursive algorithm
can be transformed to an iterative one, so if iterative algorithms
would have the property to be _decidable_ to finish - actually, they
are not - we could also say the same for a recursive one.
Recursion can often be programmed iteratively in practice. In theory, there are recursively defined functions which grow too quickly with increasing argument to be definable (or programmable) without recursion.
Have you functions like fib() in mind? - Despite they are cascaded
recursion you can create iterative ones. - But it's simpler; just
recognize that a recursion is using an implicit stack, so you can
write it in iterative form with an explicit stack. Even an extreme
function like Ackermann (which is more demanding) is not exempt to
that principle. - Or do you disagree? (Then please explain - best
with an example you may have in mind.)
Janis--
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
On 2026-09-25 15:48, Alan Mackenzie wrote:
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
[ .... ]
WRT Dude's statement it should be mentioned that a recursive algorithm >>>> can be transformed to an iterative one, so if iterative algorithms
would have the property to be _decidable_ to finish - actually, they
are not - we could also say the same for a recursive one.
Recursion can often be programmed iteratively in practice. In theory,
there are recursively defined functions which grow too quickly with
increasing argument to be definable (or programmable) without recursion.
Have you functions like fib() in mind? - Despite they are cascaded
recursion you can create iterative ones. - But it's simpler; just
recognize that a recursion is using an implicit stack, so you can
write it in iterative form with an explicit stack. Even an extreme
function like Ackermann (which is more demanding) is not exempt to
that principle. - Or do you disagree? (Then please explain - best
with an example you may have in mind.)
Yes, it was the Ackermann function I had in mind (though I'd forgotten
its name). It's a function of two natural number arguments. Simply
making both arguments the same gives a function of one argument.
If memory serves me correctly (which it probably doesn't),
A(0, 0) = 0.
A(1, 1) = 1.
A(2, 2) = 5.
A(3, 3) = 63.
A(4, 4) = 2^2^2^2^2^2^2 + 3
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:[...]
Have you functions like fib() in mind? - Despite they are cascaded
recursion you can create iterative ones. - But it's simpler; just
recognize that a recursion is using an implicit stack, so you can
write it in iterative form with an explicit stack. Even an extreme
function like Ackermann (which is more demanding) is not exempt to
that principle. - Or do you disagree? (Then please explain - best
with an example you may have in mind.)
Yes, it was the Ackermann function I had in mind (though I'd forgotten
its name). It's a function of two natural number arguments. Simply
making both arguments the same gives a function of one argument.
If memory serves me correctly (which it probably doesn't),
A(0, 0) = 0.
A(1, 1) = 1.
A(2, 2) = 5.
A(3, 3) = 63.
A(4, 4) = 2^2^2^2^2^2^2 + 3
A(5, 5) is much bigger still.
This function can't be calculated iteratively, since there's no
non-recursive way of calculating how big the requisite static arrays
would have to be. Or something like that.
Alan Mackenzie <acm@muc.de> writes:
Yes, it was the Ackermann function I had in mind (though I'd forgotten
its name). It's a function of two natural number arguments. Simply
making both arguments the same gives a function of one argument.
This function can't be calculated iteratively, since there's no non-recursive way of calculating how big the requisite static arrays
would have to be. Or something like that.
Who says the arrays have to be static? You could allocate an
array using malloc() and expand it as needed using realloc().
Or you could use a linked list.
[...]--
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */
Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
Alan Mackenzie <acm@muc.de> writes:[ .... ]
[ .... ]Yes, it was the Ackermann function I had in mind (though I'd forgotten
its name). It's a function of two natural number arguments. Simply
making both arguments the same gives a function of one argument.
This function can't be calculated iteratively, since there's no
non-recursive way of calculating how big the requisite static arrays
would have to be. Or something like that.
Who says the arrays have to be static? You could allocate an
array using malloc() and expand it as needed using realloc().
Or you could use a linked list.
You mean, implement a stack of unbounded size? If you do that, you are implementing a recursive algorithm, surely? The point under discussion
is whether or not Ackermann's function can be implemented without using recursion.
Alan Mackenzie <acm@muc.de> writes:
Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
Alan Mackenzie <acm@muc.de> writes:[ .... ]
[ .... ]Yes, it was the Ackermann function I had in mind (though I'd forgotten >>>> its name). It's a function of two natural number arguments. Simply
making both arguments the same gives a function of one argument.
This function can't be calculated iteratively, since there's no
non-recursive way of calculating how big the requisite static arrays
would have to be. Or something like that.
Who says the arrays have to be static? You could allocate an
array using malloc() and expand it as needed using realloc().
Or you could use a linked list.
You mean, implement a stack of unbounded size? If you do that, you are
implementing a recursive algorithm, surely? The point under discussion
is whether or not Ackermann's function can be implemented without using
recursion.
Yes, I mean implementing a stack of unbounded size.
It depends on what you mean by "recursive algorithm". Using an
explicit stack that can grow as needed is a way to implement
something like Ackermann's function without functions that call
themselves, directly or indirectly.
In computation theory (and the Ackermann function is only of theoretical interest - it has no practical use!), there is no difference between
loops and functions that call themselves - it is all recursion. And it doesn't matter if your "stack" is a call stack, a static array, a
heap-based linked list, or whatever.
The thing that is special about the Ackermann function is that it is not "primitive recursive". That does not mean you can't implement it with a loop and an array to hold your stack. Basically, it means that you
don't know an upper bound on your stack size in advance.
If you take something like the quicksort algorithm for comparison. That
is most clearly implemented in most languages with recursive functions,
but you can certainly handle it with loops and heap-allocated (or even alloca allocated) stacks. You can also use a single allocation for
this, because you can find an upper bound - if your input data is length "n", a stack of size n^2 will definitely be big enough.
You can implement the Ackermann function without explicit recursion,
just using a single loop and with allocated stacks or lists to hold the progress. But you /cannot/ do so with a single allocation at the start.
If you are asked to calculate A(m, n), you cannot calculate an upper
bound on the stack size you need without calculating the function.
But with malloc() and realloc(), you are good to go!--
Note that recursion isn't "necessary" to program [operations on]
tree structures. It just makes the algorithms appear simpler and
clearer, thus recursion is a sensible technique to implement
application cases like those.
Some things you need to do on trees need either explicit recursion, or "simulated recursion", where static arrays are used to hold intermediate values of variables. This approach limits the depth of a tree, possibly
more so than the size of the stack when using explicit recursion. We
might just be arguing about the meaning of words here.
[ Followup-To: set ]
In comp.theory Dude <punditster@gmail.com> wrote:
[ .... ]
You can use restricted programming languages or subsets (such as MISRA
C, SPARK, or Rocq) that are not fully Turing-complete.
MISRA C is turing-complete, just as C is. I don't know about the
others, but it is likely they are turing-complete too.
MISRA C is a subset of C which supposedly reduces error possibilities,
at the expense of bloat. As far as I'm aware, no studies have been done which show that MISRA C is in fact better than full C, for any value of "better". It is a religion in programming for automotive applications,
no more to be questioned than the Lord's Prayer in a Christian church.
By banning unbounded loops and wild recursion, you ensure that every
valid program in the language is guaranteed to finish
No. Besides, unbounded loops (such as event loops) are necessary.
Recursion is, too, if you want to program things like tree structures.
Yes, it was the Ackermann function I had in mind (though I'd
forgotten its name). It's a function of two natural number
arguments. Simply making both arguments the same gives a
function of one argument.
If memory serves me correctly (which it probably doesn't),
A(0, 0) = 0.
A(1, 1) = 1.
A(2, 2) = 5.
A(3, 3) = 63.
A(4, 4) = 2^2^2^2^2^2^2 + 3
A(5, 5) is much bigger still.
This function can't be calculated iteratively, [...]
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
On 2026-09-25 15:48, Alan Mackenzie wrote:
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
[ .... ]
WRT Dude's statement it should be mentioned that a recursive algorithm >>>> can be transformed to an iterative one, so if iterative algorithms
would have the property to be _decidable_ to finish - actually, they
are not - we could also say the same for a recursive one.
Recursion can often be programmed iteratively in practice. In theory,
there are recursively defined functions which grow too quickly with
increasing argument to be definable (or programmable) without recursion.
Have you functions like fib() in mind? - Despite they are cascaded
recursion you can create iterative ones. - But it's simpler; just
recognize that a recursion is using an implicit stack, so you can
write it in iterative form with an explicit stack. Even an extreme
function like Ackermann (which is more demanding) is not exempt to
that principle. - Or do you disagree? (Then please explain - best
with an example you may have in mind.)
Yes, it was the Ackermann function I had in mind (though I'd forgotten
its name). It's a function of two natural number arguments. Simply
making both arguments the same gives a function of one argument.
[...]
This function can't be calculated iteratively, since there's no
non-recursive way of calculating how big the requisite static arrays
would have to be. Or something like that.
[...]
On 2026-09-25 17:10, Alan Mackenzie wrote:Actually any recursive code in C can be implemented without recursion.
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
On 2026-09-25 15:48, Alan Mackenzie wrote:
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
[ .... ]
WRT Dude's statement it should be mentioned that a recursive algorithm >>>>> can be transformed to an iterative one, so if iterative algorithms
would have the property to be _decidable_ to finish - actually, they >>>>> are not - we could also say the same for a recursive one.
Recursion can often be programmed iteratively in practice.-a In theory, >>>> there are recursively defined functions which grow too quickly with
increasing argument to be definable (or programmable) without
recursion.
Have you functions like fib() in mind? - Despite they are cascaded
recursion you can create iterative ones. - But it's simpler; just
recognize that a recursion is using an implicit stack, so you can
write it in iterative form with an explicit stack. Even an extreme
function like Ackermann (which is more demanding) is not exempt to
that principle. - Or do you disagree? (Then please explain - best
with an example you may have in mind.)
Yes, it was the Ackermann function I had in mind (though I'd forgotten
its name).-a It's a function of two natural number arguments.-a Simply
making both arguments the same gives a function of one argument.
[...]
This function can't be calculated iteratively, since there's no
non-recursive way of calculating how big the requisite static arrays
would have to be.-a Or something like that.
Franky, I'm too lazy now to derive the iterative form myself. But
if you're not convinced by the principle considerations it's fairly
easy to ask an AI to create some C-code, verify that it has no
recursive calls, and check its results. - The code that the AI had
provided to me seems to work well.[*]
On 2026-09-25 17:10, Alan Mackenzie wrote:
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
On 2026-09-25 15:48, Alan Mackenzie wrote:
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
[ .... ]
WRT Dude's statement it should be mentioned that a recursive algorithm >>>>> can be transformed to an iterative one, so if iterative algorithms
would have the property to be _decidable_ to finish - actually, they >>>>> are not - we could also say the same for a recursive one.
Recursion can often be programmed iteratively in practice.-a In theory, >>>> there are recursively defined functions which grow too quickly with
increasing argument to be definable (or programmable) without
recursion.
Have you functions like fib() in mind? - Despite they are cascaded
recursion you can create iterative ones. - But it's simpler; just
recognize that a recursion is using an implicit stack, so you can
write it in iterative form with an explicit stack. Even an extreme
function like Ackermann (which is more demanding) is not exempt to
that principle. - Or do you disagree? (Then please explain - best
with an example you may have in mind.)
Yes, it was the Ackermann function I had in mind (though I'd forgotten
its name).-a It's a function of two natural number arguments.-a Simply
making both arguments the same gives a function of one argument.
[...]
This function can't be calculated iteratively, since there's no
non-recursive way of calculating how big the requisite static arrays
would have to be.-a Or something like that.
Franky, I'm too lazy now to derive the iterative form myself. But
if you're not convinced by the principle considerations it's fairly
easy to ask an AI to create some C-code, verify that it has no
recursive calls, and check its results. - The code that the AI had
provided to me seems to work well.[*]
On 2026-09-25 17:10, Alan Mackenzie wrote:
Yes, it was the Ackermann function I had in mind (though I'd forgotten
its name). It's a function of two natural number arguments. Simply
making both arguments the same gives a function of one argument.
[...]
This function can't be calculated iteratively, since there's no non-recursive way of calculating how big the requisite static arrays
would have to be. Or something like that.
Franky, I'm too lazy now to derive the iterative form myself.
But if you're not convinced by the principle considerations it's fairly
easy to ask an AI to create some C-code, verify that it has no
recursive calls, and check its results. - The code that the AI had
provided to me seems to work well.[*]
Janis--
[*] http://volatile.gridbug.de/ack_iterative.c
(only slightly adjusted version to accept command line arguments)
The point is (and it's already be covered in this thread) that there is
no way in advance to know how big a stack you will need to calculate
A(m, n) even when you know m and n.-a It is not sufficient to just pick a big number and halt with an error message if you exceed it.-a The actual iterative or recursive form of the algorithm doesn't matter.
David Brown clarified on Saturday what I really should have said, had I
been on the ball with computing theory. The Ackermann function is not _primitive recursive_. It can't be calculated in any bounded amount of storage which can be determined at the start of the calculation.
Your iterative solution will be continually increasing the amount of
store it uses as it goes along. A normal way of doing this implicitly
is with recursion.
I don't think we're really in disagreement about anything substantial
here.
Chris M. Thomasson <chris.m.thomasson.1@gmail.com> wrote:
On 9/25/2026 8:10 AM, Alan Mackenzie wrote:
[...]
Recursion in AppleSoft BASIC:
https://pastebin.com/raw/Effeg8cK
You've snipped all the context, you've given an unexplained URL, and
you've posted a quite long BASIC program [snipped] in a C group. This program is unexplained and severely lacking in comments. Does it have anything to do with the discussion about Ackermann's function?
What am I supposed to make of your post?
[ BASIC program snipped ]
On 9/25/2026 8:10 AM, Alan Mackenzie wrote:
[...]
Recursion in AppleSoft BASIC:
https://pastebin.com/raw/Effeg8cK
On 9/30/2026 12:57 PM, Alan Mackenzie wrote:
Chris M. Thomasson <chris.m.thomasson.1@gmail.com> wrote:
On 9/25/2026 8:10 AM, Alan Mackenzie wrote:
[...]
Recursion in AppleSoft BASIC:
https://pastebin.com/raw/Effeg8cK
You've snipped all the context, you've given an unexplained URL, and
you've posted a quite long BASIC program [snipped] in a C group.-a This
program is unexplained and severely lacking in comments.-a Does it have
anything to do with the discussion about Ackermann's function?
What am I supposed to make of your post?
[ BASIC program snipped ]
Using a manual stack for recursion in AppleSoft BASIC.
| Sysop: | Amessyroom |
|---|---|
| Location: | Fayetteville, NC |
| Users: | 74 |
| Nodes: | 6 (0 / 6) |
| Uptime: | 121:16:21 |
| Calls: | 1,194 |
| Files: | 1,352 |
| Messages: | 290,208 |