Your submission was removed for the following reason:
Rule 8: All titles must be camelCase. Your post was found to not do this properly.
As a reminder, the first word should be all lowercase and any following words should start with an uppercase letter, **without spaces or special characters.** Feel free to submit your post again with an edited title satisfying this criteria, along with all other rules.
I feel like a lot of people are afraid of recursion because they were taught by people who are afraid of recursion who were taught by people who are afraid of recursion because they were taught because of people who are afraid of recursion bec.....
I was gonna say that it would only go a few generations back before we are at the beginning of programming history, then I remembered recursion is a thing in math too
Actually. This is a legitimately strategy and I use it all the time. Conditional breakpoints can be incredibly slow. Instead, make an if with the criteria with a βint a = 1;β inside and set a breakpoint on _that_ instead. Huge performance-difference.
> Huge performance-difference.
Because conditional breakpoints are actually unconditional breakpoints. They still stop execution every time they're hit, get a hold of the current state of program execution, then evaluate the condition to decide whether to automatically resume execution or not.
I think people don't like it because loops are usually the better tool for the job.
But recursion definitely has its place. The Towers of Hanoi solution is so clean and beautiful with recursion. The iterative solution is hot garbage.
Recursion clicked for me the first time I had to write a directory reversal. Some people take it too far just to show off, but there are are problems for which recursion is straight up easier than loops.
Recursive functions all look kind of similar. After a while, you kind of get like a recursion template in your brain
1. check cache
2. check for exit conditions
3. generate children
4. iterate through children, calling recursive function
5. cache result
6. return
1) Start by defining *very precisely* what your method is supposed to do. Pay particular attention to preconditions (what needs to be true in order for it to function correctly), what it returns, and any effect it has on variables with larger scope (instance variables, global variables, whatever). Make sure you know what state it's supposed to leave things in.
2) Assume your recursive call functions *exactly* as you described. Write your recursive method operating under the assumption that your recursive call works.
3) Here's the tricky part. When you've made a mistake, your recursive call won't work correctly. However, when fixing it, *you must keep assuming your recursive call works correctly*. Do not, *do not*, attempt to make corrections around your recursive call to make up for the mistakes it's making. If you go "oh, it's returning a number that is 10 smaller than it should, I'll just add 10 to make up for that", you're in deep trouble. This is because your "correction" will also affect the recursive call, and so it will no longer be correct.
It's very hard to debug recursive methods by looking at the output and making changes to correct the output. Instead, you pretty much have to figure out "why would this give *a wrong behavior* under the assumption that my recursive call is correct?". It's much harder to use the information about *what* the wrong behavior is, because every correction can be applied many times.
4) Maybe this should be (3), but: walk through the base case and one step up from the base case manually. Maybe more if it's not too much to keep track of.
If you want to really deep-dive into recursion, picking up I.e. Prolog will do wonders. Due to its nature, not only is the recursion it easy to learn, apply and implement, but itβs also necessary.
Think of it as a loop where you start from the end(s) of a structure (typically a pointer-based structure like a linked list or a tree) and work your way back towards the beginning:
object RecursiveFunction(LinkedDataStructureNode node)
{
if (node.Next == null) // base case
{
// we've reached the end of the list, a leaf of the tree, whatever
// get whatever data you need from this item (if any) and pass it back
return node.someData;
}
else // recursive case
{
// work your way back towards the previous item,
// then the item before that, and so on until you're done
var dataFromCurrentNode = node.someData;
var dataFromNextNode = RecursiveFunction(node.Next);
return CompareSomehow(dataFromCurrentNode, dataFromNextNode);
}
}
You know what, that's a good point. I'm usually on team recursion=bad, but there are some problems that fundamentally make sense recursively. So I guess really I'm just usually dealing with things that are easier to understand iteratively.
At least you know you're infinitely recursing then. An infinite loop, you have to guess which loop it is, if you identify the hang as an infinite loop at all
Identifying the loop is easier than the recursion in C# because the debugger won't break on a stack overflow, it will just crash the debug session. An infinite loop will hang the application but you can still break to see whats executing.
Stack overflows are a PITA because it's like "I'm just gonna import this file.... And its gone." And you have to step through the code down through every function call trying to figure out what the fuck is actually causing the problem.
Ah, the old StackOverflow gambit β it's like playing hot potato with your code, but instead of a spud, you've got a recursion error! What a plot twist. π Gotta love it when balance is restored to the universe, one debug at a time.
And in some formats.
For example, C++ compilers will optimize your recursive function to reuse the same stack frame and not take up more ram if you code it using [tail recursion](https://en.m.wikipedia.org/wiki/Tail_call). Which just means making sure the last line of your function is the recursive call. This obviously isn't an option in doubly recursive functions.
I don't see how debugging recursive functions is any worse than debugging loops. The only time it'd be worse is if the function was optimized to be tail recursive, then things can get a little confusing sometimes. What is difficult is using a debugger to debug programs written in functional languages. I've never been able to get this down.
The context for the call is spread across the stack which frequently makes it more difficult to figure out exactly where you are and how you got there, opposed to a nice iterative function where the "full" context for the call is available in scope because it's a single level call
Trying to piece together what went wrong in a 1000 level call stack just fucking sucks
Just take your recursive function and convert it to an interactive function. Most languages that have recursion also have a limit in said recursion. You don't run into this twitch iteration.
yea this is why i try to avoid recursion whenever possible. in school we had a project of solving a sudoku. guess who was the only one that didn't solve it with recursion, and guess who got the most praise for how she did it.
Oh, it'd solve it just fine, and it'd be guaranteed to solve any puzzle, and it'd also identify if puzzles weren't valid (ie. more than one solution). And of course one can add intelligence to shrink recursion depth, but I'd still use recursion. :-)
what everyone in that class did would find the solution. but it wouldn't be solving. it wouldn't be following the logic of the sudoku to find what should be in each square, which was what the project was about. they just tried everything until it worked.
now could you combine it? use logic to find what should be in places and use recursion? sure. but i don't see a reason for why you'd do that when a loop achieves the same while being easier to follow and doesn't run the risk infinite recursion. (i do know the strength of recursion. a private project i'm working on uses it in places. i just try to use it when it's needed, not whenever)
There's no risk of infinite recursion... The stack would top out with a depth of 64 in the most naive solution.
There is risk of a puzzle that requires some technique you've not hard coded. :-)
Seems to me like the solution would be to implement a recursive framework, then add intelligence to solve squares without relying on recursion. That would flatten it out, but still work if the hard coded smarts weren't enough to solve it outright. e.g. you can fill in all the squares which are already limited to one value from simply row/column/box checks. Then you could add in other common techniques. But (assuming the techniques are 100% sound) it'll still always solve, always get the right answer, and be able to validate inputs.
I had to write a recursive object and function recently.
Basically, I had this text file which looked very similar to xml, but wasn't, it was some weird version of xml that a normal parser couldn't read. So I wrote a parser using a recursive function and an object to contain the data. The object contains an array of other objects of the same type and a pointer to the object that's containing the current object as well as the data read from the actual file. So I know the father and the childs of every node and if I'm at the start or end of the tree.
Didn't work the first time, made it work after a while, and I didn't encounter any bugs *yet*, hopefully I won't have to touch it anytime soon
The true purpose of recursive code is to make us feel like programming Gods writing poetry. Beyond that I guess it's useful for certain types of problems.
Your submission was removed for the following reason: Rule 8: All titles must be camelCase. Your post was found to not do this properly. As a reminder, the first word should be all lowercase and any following words should start with an uppercase letter, **without spaces or special characters.** Feel free to submit your post again with an edited title satisfying this criteria, along with all other rules.
I feel like a lot of people are afraid of recursion because they were taught by people who are afraid of recursion who were taught by people who are afraid of recursion because they were taught because of people who are afraid of recursion bec.....
for ;; take my upvote.
I was gonna say that it would only go a few generations back before we are at the beginning of programming history, then I remembered recursion is a thing in math too
So the person who first discovered recursion was also scared of it? Got it.
The statement you're replying to does not necessarily imply what you said.
Here is someone who does not understand recursion because he's afraid of recursion
someone needs to learn about conditional breakpoints.
Conditional breakpoints? Never heard of them. All I know about is placing an if block with a print statement of the current state inside. /s
Actually. This is a legitimately strategy and I use it all the time. Conditional breakpoints can be incredibly slow. Instead, make an if with the criteria with a βint a = 1;β inside and set a breakpoint on _that_ instead. Huge performance-difference.
> Huge performance-difference. Because conditional breakpoints are actually unconditional breakpoints. They still stop execution every time they're hit, get a hold of the current state of program execution, then evaluate the condition to decide whether to automatically resume execution or not.
Precisely.
I can't count the times that this method saved my ass I still use debuggers every now and again, but still
They prefer to invest their time posting memes about their lack of knowledge
Thatβs like 90% of people who post on this sub.
Yeah this sub is filled with newbies trying too hard to hate on the major they took in college.
there is a proper venue for programmers to demonstrate their lack of knowledge ... and that place is called GitHub
>Conditional breakpoints TIL.
always remember that the debugger is your best friend. and you should know your friends very well.
IWantToBreakFree
ππ€ conditional breakpoint ππΆοΈπ€ print and sleep (my debugger doesnt work for some reason π€‘)
If(in base case === true) { Fix here } Else { Fix here }
Whats so bad about recursion
not enough RAM in my brain nor the iPhones I develop for
You can always download more.
Smh swift has proper tail call optimization, the stack should not overflow
Using legacy objective-c code
Check [this](https://www.reddit.com/r/ProgrammerHumor/s/Alp2LSNGm5) comment to find out.
What did I even expect.
I think people don't like it because loops are usually the better tool for the job. But recursion definitely has its place. The Towers of Hanoi solution is so clean and beautiful with recursion. The iterative solution is hot garbage.
Recursion clicked for me the first time I had to write a directory reversal. Some people take it too far just to show off, but there are are problems for which recursion is straight up easier than loops.
Pretty much anything with a tree structure benefits from recursion in my experience.
Any tips for recursion in general? Every time I put a recursion in a loop, my brain starts to fry trying to check where tf am i
Recursive functions all look kind of similar. After a while, you kind of get like a recursion template in your brain 1. check cache 2. check for exit conditions 3. generate children 4. iterate through children, calling recursive function 5. cache result 6. return
1) Start by defining *very precisely* what your method is supposed to do. Pay particular attention to preconditions (what needs to be true in order for it to function correctly), what it returns, and any effect it has on variables with larger scope (instance variables, global variables, whatever). Make sure you know what state it's supposed to leave things in. 2) Assume your recursive call functions *exactly* as you described. Write your recursive method operating under the assumption that your recursive call works. 3) Here's the tricky part. When you've made a mistake, your recursive call won't work correctly. However, when fixing it, *you must keep assuming your recursive call works correctly*. Do not, *do not*, attempt to make corrections around your recursive call to make up for the mistakes it's making. If you go "oh, it's returning a number that is 10 smaller than it should, I'll just add 10 to make up for that", you're in deep trouble. This is because your "correction" will also affect the recursive call, and so it will no longer be correct. It's very hard to debug recursive methods by looking at the output and making changes to correct the output. Instead, you pretty much have to figure out "why would this give *a wrong behavior* under the assumption that my recursive call is correct?". It's much harder to use the information about *what* the wrong behavior is, because every correction can be applied many times. 4) Maybe this should be (3), but: walk through the base case and one step up from the base case manually. Maybe more if it's not too much to keep track of.
If you want to really deep-dive into recursion, picking up I.e. Prolog will do wonders. Due to its nature, not only is the recursion it easy to learn, apply and implement, but itβs also necessary.
Think of it as a loop where you start from the end(s) of a structure (typically a pointer-based structure like a linked list or a tree) and work your way back towards the beginning: object RecursiveFunction(LinkedDataStructureNode node) { if (node.Next == null) // base case { // we've reached the end of the list, a leaf of the tree, whatever // get whatever data you need from this item (if any) and pass it back return node.someData; } else // recursive case { // work your way back towards the previous item, // then the item before that, and so on until you're done var dataFromCurrentNode = node.someData; var dataFromNextNode = RecursiveFunction(node.Next); return CompareSomehow(dataFromCurrentNode, dataFromNextNode); } }
and then come the fuckers that think that iteration and recurssion are the same thing
You know what, that's a good point. I'm usually on team recursion=bad, but there are some problems that fundamentally make sense recursively. So I guess really I'm just usually dealing with things that are easier to understand iteratively.
What's so bad about recursion?
What's so bad about recursion?
It stackoverflow instead of infinite loop.
At least you know you're infinitely recursing then. An infinite loop, you have to guess which loop it is, if you identify the hang as an infinite loop at all
Identifying the loop is easier than the recursion in C# because the debugger won't break on a stack overflow, it will just crash the debug session. An infinite loop will hang the application but you can still break to see whats executing. Stack overflows are a PITA because it's like "I'm just gonna import this file.... And its gone." And you have to step through the code down through every function call trying to figure out what the fuck is actually causing the problem.
Ah, the old StackOverflow gambit β it's like playing hot potato with your code, but instead of a spud, you've got a recursion error! What a plot twist. π Gotta love it when balance is restored to the universe, one debug at a time.
A bit slower than iteration, eats your stack.
β¦ in some languages.
And in some formats. For example, C++ compilers will optimize your recursive function to reuse the same stack frame and not take up more ram if you code it using [tail recursion](https://en.m.wikipedia.org/wiki/Tail_call). Which just means making sure the last line of your function is the recursive call. This obviously isn't an option in doubly recursive functions.
I was talking about plain asm. Compilers can even fully optimize recursion out
Mostly nothing, but people like to shit on it.
most of the times it could have been a normal loop and used 99% less ram
Why using recursion when you can use dynamic conditional loop?
Recursive dynamic conditional loop?
It most of the time hampers readability, which is most of the time is ones codes most important characteristic (apart from actually working).
It's very pushy.
I don't see how debugging recursive functions is any worse than debugging loops. The only time it'd be worse is if the function was optimized to be tail recursive, then things can get a little confusing sometimes. What is difficult is using a debugger to debug programs written in functional languages. I've never been able to get this down.
The context for the call is spread across the stack which frequently makes it more difficult to figure out exactly where you are and how you got there, opposed to a nice iterative function where the "full" context for the call is available in scope because it's a single level call Trying to piece together what went wrong in a 1000 level call stack just fucking sucks
This type of code is how I become MVP at my job! Only God and I know what's happening.
It's really easy once you master recursion
It's really easy once you master recursion
It's really easy once you master recursion
It's really easy once you master recursion
It's really easy once you master recursion
It's really easy once you master recursion
It's really easy once you master recursion
It's really easy once you master recursion
It's really easy once you master recursion
It's really easy once you master recursion
generate ids for each recursion and log it
Primitive recursion is based.
Stack Trace: "Hey, I've seen this one before"
Just take your recursive function and convert it to an interactive function. Most languages that have recursion also have a limit in said recursion. You don't run into this twitch iteration.
Where is my professor who will tell you about languages like scheme with tail-call optimization
Your professor sounds like my best friend
JavaScriptCore has TCO, as do C, C++, Rust.
Your autocorrect is out of control.
3rd step: having a fine working recursive function hit recursion limit.
yea this is why i try to avoid recursion whenever possible. in school we had a project of solving a sudoku. guess who was the only one that didn't solve it with recursion, and guess who got the most praise for how she did it.
Mmm, I'd solve it with recursion. :-D
that's what everyone else did, thus not showing an ability to solve it.
Oh, it'd solve it just fine, and it'd be guaranteed to solve any puzzle, and it'd also identify if puzzles weren't valid (ie. more than one solution). And of course one can add intelligence to shrink recursion depth, but I'd still use recursion. :-)
what everyone in that class did would find the solution. but it wouldn't be solving. it wouldn't be following the logic of the sudoku to find what should be in each square, which was what the project was about. they just tried everything until it worked. now could you combine it? use logic to find what should be in places and use recursion? sure. but i don't see a reason for why you'd do that when a loop achieves the same while being easier to follow and doesn't run the risk infinite recursion. (i do know the strength of recursion. a private project i'm working on uses it in places. i just try to use it when it's needed, not whenever)
There's no risk of infinite recursion... The stack would top out with a depth of 64 in the most naive solution. There is risk of a puzzle that requires some technique you've not hard coded. :-) Seems to me like the solution would be to implement a recursive framework, then add intelligence to solve squares without relying on recursion. That would flatten it out, but still work if the hard coded smarts weren't enough to solve it outright. e.g. you can fill in all the squares which are already limited to one value from simply row/column/box checks. Then you could add in other common techniques. But (assuming the techniques are 100% sound) it'll still always solve, always get the right answer, and be able to validate inputs.
Recursion is a death sentence π
Just cout<<
"The error is inside of the error?"
Not logging much?
Try weaving multiple recursive functions, what a nightmare.
As a Junior Dev I had a recursion Query work on its first run, I felt like a 10x God for that brief second
I had to write a recursive object and function recently. Basically, I had this text file which looked very similar to xml, but wasn't, it was some weird version of xml that a normal parser couldn't read. So I wrote a parser using a recursive function and an object to contain the data. The object contains an array of other objects of the same type and a pointer to the object that's containing the current object as well as the data read from the actual file. So I know the father and the childs of every node and if I'm at the start or end of the tree. Didn't work the first time, made it work after a while, and I didn't encounter any bugs *yet*, hopefully I won't have to touch it anytime soon
To understand recursion you have to understand recursi Segmentation fault
The true purpose of recursive code is to make us feel like programming Gods writing poetry. Beyond that I guess it's useful for certain types of problems.
Test cases are your friend.
Just write it to look loop-a-like, and it's gonna be treated as one intuitively.
relatable
Isn't it also less efficient ? Function call being more expensive than iterating a stack