Never write another loop again
-
i learned a bit of programming the other day whilst viewing a YouTube video w/ the intriguing title "Never write another loop again" . in particular re/ recursion "trailing call optimization" sometimes performed by compilers but i do not see why it can not be done by hand . namely instead of :
void recurse(int count)
{
if (count == 0) return;
recurse(count-1);
}this :
void recurse(int count)
{
start:
if (count == 0) return;
count -= 1;
goto start;
}so the stack is never destroyed regardless of the depth of the recursion which is why i have always shunned recursion but now i have a new toy to play with .
-
i learned a bit of programming the other day whilst viewing a YouTube video w/ the intriguing title "Never write another loop again" . in particular re/ recursion "trailing call optimization" sometimes performed by compilers but i do not see why it can not be done by hand . namely instead of :
void recurse(int count)
{
if (count == 0) return;
recurse(count-1);
}this :
void recurse(int count)
{
start:
if (count == 0) return;
count -= 1;
goto start;
}so the stack is never destroyed regardless of the depth of the recursion which is why i have always shunned recursion but now i have a new toy to play with .
BernardIE5317 wrote:
so the stack is never destroyed regardless of the depth of the recursion which is why i have always shunned recursion but now i have a new toy to play with.
I wish more programmers cared about stuff like this. I mean, don't get me wrong I'm a functional programming fanboy. So, in my world I'm tossing stacks around like they're going out of style. Still, it's nice to see peeps care about stuff like this in a world where few people understand things like all strings are immutable and every concatenation is a reconstruction of objects, etc.
Jeremy Falcon
-
i learned a bit of programming the other day whilst viewing a YouTube video w/ the intriguing title "Never write another loop again" . in particular re/ recursion "trailing call optimization" sometimes performed by compilers but i do not see why it can not be done by hand . namely instead of :
void recurse(int count)
{
if (count == 0) return;
recurse(count-1);
}this :
void recurse(int count)
{
start:
if (count == 0) return;
count -= 1;
goto start;
}so the stack is never destroyed regardless of the depth of the recursion which is why i have always shunned recursion but now i have a new toy to play with .
Side note, if you ever pull off something like that in a real-world project, that's the kinda thing that deserves a comment explaining why. Most devs will probably look at that goto and consider it a code smell if they don't know the why. I should say, if the goal is to prevent recursion, it's a good thing. If the goal is to prevent using a loop construct, you're better off not using the goto realistically.
Jeremy Falcon
-
i learned a bit of programming the other day whilst viewing a YouTube video w/ the intriguing title "Never write another loop again" . in particular re/ recursion "trailing call optimization" sometimes performed by compilers but i do not see why it can not be done by hand . namely instead of :
void recurse(int count)
{
if (count == 0) return;
recurse(count-1);
}this :
void recurse(int count)
{
start:
if (count == 0) return;
count -= 1;
goto start;
}so the stack is never destroyed regardless of the depth of the recursion which is why i have always shunned recursion but now i have a new toy to play with .
One of my least favorite tasks is converting a recursive function to an iterative one. It comes up more than I'd like because of embedded and limited stack space forcing my hand. Still, it's rewarding once it's done.
Check out my IoT graphics library here: https://honeythecodewitch.com/gfx And my IoT UI/User Experience library here: https://honeythecodewitch.com/uix
-
i learned a bit of programming the other day whilst viewing a YouTube video w/ the intriguing title "Never write another loop again" . in particular re/ recursion "trailing call optimization" sometimes performed by compilers but i do not see why it can not be done by hand . namely instead of :
void recurse(int count)
{
if (count == 0) return;
recurse(count-1);
}this :
void recurse(int count)
{
start:
if (count == 0) return;
count -= 1;
goto start;
}so the stack is never destroyed regardless of the depth of the recursion which is why i have always shunned recursion but now i have a new toy to play with .
-
Personally I would rather write code that's easy to read and understand and let the compiler optimize the tail recursion.
Also giving you a thumbs up because a compiler can unroll loops for sure. I'm not a compiler guru though, but it was always my understanding you had no guarantee of how it did so. But, of course, you have to trust if someone is smart enough to write a compiler than can figure this out. However, I also give the OP a thumbs up, because it's nice to see people caring enough to actually continue to learn the craft. Unfortunately, there are still a lot of programmers that don't even know what the stack is, much less care about it.
Jeremy Falcon
-
i learned a bit of programming the other day whilst viewing a YouTube video w/ the intriguing title "Never write another loop again" . in particular re/ recursion "trailing call optimization" sometimes performed by compilers but i do not see why it can not be done by hand . namely instead of :
void recurse(int count)
{
if (count == 0) return;
recurse(count-1);
}this :
void recurse(int count)
{
start:
if (count == 0) return;
count -= 1;
goto start;
}so the stack is never destroyed regardless of the depth of the recursion which is why i have always shunned recursion but now i have a new toy to play with .
I wouldn't write either of those. And I might point the author to a page about if-less programming as well.
-
i learned a bit of programming the other day whilst viewing a YouTube video w/ the intriguing title "Never write another loop again" . in particular re/ recursion "trailing call optimization" sometimes performed by compilers but i do not see why it can not be done by hand . namely instead of :
void recurse(int count)
{
if (count == 0) return;
recurse(count-1);
}this :
void recurse(int count)
{
start:
if (count == 0) return;
count -= 1;
goto start;
}so the stack is never destroyed regardless of the depth of the recursion which is why i have always shunned recursion but now i have a new toy to play with .
-
i learned a bit of programming the other day whilst viewing a YouTube video w/ the intriguing title "Never write another loop again" . in particular re/ recursion "trailing call optimization" sometimes performed by compilers but i do not see why it can not be done by hand . namely instead of :
void recurse(int count)
{
if (count == 0) return;
recurse(count-1);
}this :
void recurse(int count)
{
start:
if (count == 0) return;
count -= 1;
goto start;
}so the stack is never destroyed regardless of the depth of the recursion which is why i have always shunned recursion but now i have a new toy to play with .
Sorry to be the party pooper, but I don't see the point of either one (assuming they are C code). C has call-by-value semantics so the first one descends on a stack without any benefit and the second one loops for no apparent reason. Also I don't see how the 2nd one is better than the equally useless:
void loop(int count)
{
while (count--)
;
}Maybe I'm missing something...
Mircea
-
Also giving you a thumbs up because a compiler can unroll loops for sure. I'm not a compiler guru though, but it was always my understanding you had no guarantee of how it did so. But, of course, you have to trust if someone is smart enough to write a compiler than can figure this out. However, I also give the OP a thumbs up, because it's nice to see people caring enough to actually continue to learn the craft. Unfortunately, there are still a lot of programmers that don't even know what the stack is, much less care about it.
Jeremy Falcon
Unrolling loops is a complex task beacuse to have any benefit you can unroll to a maximum of a certain size that depends on the target processor. Depending on the structure of the loop and it's compiled size the amount of unrolls may vary drastically. I had to write some extra high performance libraries in assembler - the only way to use SIMD effectively - and I had to unroll the loops manually.
GCS/GE d--(d) s-/+ a C+++ U+++ P-- L+@ E-- W+++ N+ o+ K- w+++ O? M-- V? PS+ PE Y+ PGP t+ 5? X R+++ tv-- b+(+++) DI+++ D++ G e++ h--- r+++ y+++* Weapons extension: ma- k++ F+2 X The shortest horror story: On Error Resume Next
-
i learned a bit of programming the other day whilst viewing a YouTube video w/ the intriguing title "Never write another loop again" . in particular re/ recursion "trailing call optimization" sometimes performed by compilers but i do not see why it can not be done by hand . namely instead of :
void recurse(int count)
{
if (count == 0) return;
recurse(count-1);
}this :
void recurse(int count)
{
start:
if (count == 0) return;
count -= 1;
goto start;
}so the stack is never destroyed regardless of the depth of the recursion which is why i have always shunned recursion but now i have a new toy to play with .
It's still a loop. :rolleyes:
Latest Articles:
A Lightweight Thread Safe In-Memory Keyed Generic Cache Collection Service A Dynamic Where Implementation for Entity Framework -
Sorry to be the party pooper, but I don't see the point of either one (assuming they are C code). C has call-by-value semantics so the first one descends on a stack without any benefit and the second one loops for no apparent reason. Also I don't see how the 2nd one is better than the equally useless:
void loop(int count)
{
while (count--)
;
}Maybe I'm missing something...
Mircea
The OP left out the actual function to focus on the semantics of the loop/recursion. In real code there'd be something between the start of the code and the 'if'.
-
i learned a bit of programming the other day whilst viewing a YouTube video w/ the intriguing title "Never write another loop again" . in particular re/ recursion "trailing call optimization" sometimes performed by compilers but i do not see why it can not be done by hand . namely instead of :
void recurse(int count)
{
if (count == 0) return;
recurse(count-1);
}this :
void recurse(int count)
{
start:
if (count == 0) return;
count -= 1;
goto start;
}so the stack is never destroyed regardless of the depth of the recursion which is why i have always shunned recursion but now i have a new toy to play with .
BernardIE5317 wrote:
i have always shunned recursion
It's nice to know that I'm not the only one who likes to avoid using recursion. There are instances where I have implemented it (e.g. developing a custom file system, or tiered menu), but I'm superstitious about the way I code. I'm superstitious about datatypes and parentheses, too. Even if I know a variable is an integer, I redundantly cast it as an integer just to be absolutely sure. I can't help it. Even though I write code that adheres to the order of operations, I use parentheses just to make sure it operates in the proper order.
-
BernardIE5317 wrote:
i have always shunned recursion
It's nice to know that I'm not the only one who likes to avoid using recursion. There are instances where I have implemented it (e.g. developing a custom file system, or tiered menu), but I'm superstitious about the way I code. I'm superstitious about datatypes and parentheses, too. Even if I know a variable is an integer, I redundantly cast it as an integer just to be absolutely sure. I can't help it. Even though I write code that adheres to the order of operations, I use parentheses just to make sure it operates in the proper order.
i am superstitious also but just the opposite . i liberaly use
auto xyz = somthing;
and insist on no parenthesis unless required after carefully studing the precedence chart which i do frequently . -
BernardIE5317 wrote:
i have always shunned recursion
It's nice to know that I'm not the only one who likes to avoid using recursion. There are instances where I have implemented it (e.g. developing a custom file system, or tiered menu), but I'm superstitious about the way I code. I'm superstitious about datatypes and parentheses, too. Even if I know a variable is an integer, I redundantly cast it as an integer just to be absolutely sure. I can't help it. Even though I write code that adheres to the order of operations, I use parentheses just to make sure it operates in the proper order.
Steve Raw wrote:
the only one who likes to avoid using recursion
There are certainly cases where it makes sense since there is no expectation that the business would need more. And example is recursing on an asset tree which users work. There is of course no reason for a user to use a tree that is, for example, 1,000 deep. But I still enforce it by passing a depth variable. I don't do that really due to users doing something silly but rather because developers (including me) doing something silly and producing an endless loop.
Steve Raw wrote:
I use parentheses just to make sure it operates in the proper order.
I do too. Makes it obvious to a maintainer what order I expected rather than leaving it up to them to verify every time it is looked at that the order represents what is actually needed. Not to mention of course that doing it all the time means one does not get surprised by things like the precedence order for inline conditionals (question mark and colon). Which I have seen people get wrong.
-
i am superstitious also but just the opposite . i liberaly use
auto xyz = somthing;
and insist on no parenthesis unless required after carefully studing the precedence chart which i do frequently .I use auto a lot but I despise precedence and ALWAYS use parenthesis. I think the whole idea of operators having precedence is really stupid.
"They have a consciousness, they have a life, they have a soul! Damn you! Let the rabbits wear glasses! Save our brothers! Can I get an amen?"
-
I use auto a lot but I despise precedence and ALWAYS use parenthesis. I think the whole idea of operators having precedence is really stupid.
"They have a consciousness, they have a life, they have a soul! Damn you! Let the rabbits wear glasses! Save our brothers! Can I get an amen?"
is it stupid because there is no logic from which the rules can be deduced making them arbitrary ?
-
is it stupid because there is no logic from which the rules can be deduced making them arbitrary ?
That's one reason. Another is why should one operator have precedence over another? I can't think of a good reason.
"They have a consciousness, they have a life, they have a soul! Damn you! Let the rabbits wear glasses! Save our brothers! Can I get an amen?"
-
Sorry to be the party pooper, but I don't see the point of either one (assuming they are C code). C has call-by-value semantics so the first one descends on a stack without any benefit and the second one loops for no apparent reason. Also I don't see how the 2nd one is better than the equally useless:
void loop(int count)
{
while (count--)
;
}Maybe I'm missing something...
Mircea
i eventually came to the same conclusion .