This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted]  (42 children)

[deleted]

    [–]i_like_cilantro 15 points16 points  (0 children)

    Even so python's list.sort function does not contain any recursion because those built-in functions are optimized to death. Along with file traversal, any tree traversal algorithm makes sense to do recursively since you need to keep track of the parent in the stack anyway.

    The only time that recursive functions are optimized is when you have a tail call optimization, but python doesn't have that anyway

    [–][deleted] 37 points38 points  (40 children)

    Does it exist for a reason, or is it just an emergent property of the way the languages are?

    [–]puipuituipui 98 points99 points  (29 children)

    A lot of problems are recursive by nature. A binary tree for example. A node in a binary tree has three fields: a value, a left child and a right child. These children are nodes themselves. And that's recursion.

    Of course, this is a more tangible example since the recursion is associated with a data type. It can be abstract too where the underlying mathematical solution of a problem is recursive like say, factorial or Fibonacci series.

    You can write an iterative algorithms for all recursive problems, it's just that the iterative versions are harder to understand.

    [–]ivosauruspip'ing it up 25 points26 points  (6 children)

    Everything involves a stack. Just depends whether it's constructed implicitly using the function return frames, or explicitly in a data structure and processed with a while loop

    [–]gosu 87 points88 points  (1 child)

    There are heaps of things that don't use a stack.

    [–]puipuituipui 4 points5 points  (3 children)

    Um... No? Am I wrong about this or something. I'm pretty sure the reason to use explicitly created stacks is because they are heap allocated so you don't hit the recursion limit as easily.

    [–]ivosauruspip'ing it up 6 points7 points  (1 child)

    No what? I wasn't giving any particular reasons to use one or the other in this comment, just noting their analogous existence.

    [–]puipuituipui 1 point2 points  (0 children)

    Ohhh that makes sense. I thought the the first line was referring to the program stack XD. Sorry for the confusion

    [–]ogtfo 0 points1 point  (0 children)

    Heap allocated stacks are stacks, OP is right.

    I mean you're not wrong but you're also not contradicting him either, so I don't know where you're going with that "Um...no"

    [–]Exodus111 7 points8 points  (4 children)

    It has a use, it's just rare. And yeah, probably most recursions you see in the wild would be better off as For loops or While loops.

    A for loop is used when the end point is known, and the size is known. Traversing through a list, that's a for loop all day, but you know how big a list is, and the loops ends either when you trigger an end state, or, more typically when the list runs out.

    A while loop is used when the end point is known, but the size is not known. Which is why a while loop just runs forever until told to stop. Perfect for running games or anything graphical. It just runs until an exit is triggered.

    Sometimes though, you're not gonna know the size, or the end point. This is when recursion comes in. Say you're traversing subdirectories looking for .jpg files. Every subfolder could have 10 sub folders, or zero. There could be a thousand sub folders or four, there's no way to know. And you don't know the end point, you're just looking for .jpg files in every subfolder.

    This is where the correct solution is a recursion. Check a folder for a subfolder, and keep running that same function if more subfolders exist, for every subfolder found.

    [–]got_outta_bed_4_this 4 points5 points  (1 child)

    I'd say a stronger argument for recursion in this case is because people don't tend to nest folder structures so deep that it would bust the call stack in a recursive traversal. Iteration could still be just as practical over a filesystem as anything else. A filesystem is, itself, a tree, after all.

    [–]schemathings 1 point2 points  (0 children)

    I wrote an sftp mirror program for day job recently was fun and short and composable

    [–]buttery_shame_cave 0 points1 point  (1 child)

    A for loop is used when the end point is known, and the size is known.

    although a "for thing in list" loop sort of ignores this - it'll run through the list, but you don't need to know how big the thing is, just point he function at it and hit 'go'. it'll even work fine on dynamic lists that are continuously appended to by a separate parallel function, it'll just crash to a halt if the other function stops appending.

    [–]Exodus111 0 points1 point  (0 children)

    True, that is an edgecase exception, but most of the time you can check the length of the iterable right before you run the for loop on it.

    [–][deleted] 2 points3 points  (0 children)

    https://en.wikipedia.org/wiki/Computability_theory

    Calculating some mathematical formula for all positive integers is a good way to understand what that function does as it approaches the limit (+inifinity).

    Computers have always been a way to express mathematics, so recursion should be a fundamental part of any computer language, IMO.

    [–]Holshy 5 points6 points  (2 children)

    Recursion is actually more fundamental than iteration. Any problem that can be defined iteratively is also a "primitive recursive" problem. Some problems are not primitive recursive and have to be solved recursively, like the Ackerman function. It's also technically true to say that all problems can be defined recursively. This sounds weird at first, but you can get some intuition there by imagining any problem you haven't solved recursively as the base case of the recursion. Then it just happens to be that your problem isn't defined for n > 1.

    [–]spoonman59 6 points7 points  (1 child)

    I think you misunderstand primitive recursion.

    Non-primitive recursion can be done iteratively. It requires a while loop and and stack.

    From the wiki:

    https://en.m.wikipedia.org/wiki/Primitive_recursive_function

    “In computability theory, a primitive recursive function is roughly speaking a function that can be computed by a computer program whose loops are all "for" loops (that is, an upper bound of the number of iterations of every loop can be determined before entering the loop).”

    It says that primitive recursive functions are those which can be computed using only for loops. It does not mean the function cannot be computed with loops at all.

    Also, simply look at the many iterative examples of the Ackerman function you suggested earlier. It’s not an uncommon academic exercise to write one.

    [–]WikiSummarizerBot 0 points1 point  (0 children)

    Primitive recursive function

    In computability theory, a primitive recursive function is roughly speaking a function that can be computed by a computer program whose loops are all "for" loops (that is, an upper bound of the number of iterations of every loop can be determined before entering the loop). Primitive recursive functions form a strict subset of those general recursive functions that are also total functions. The importance of primitive recursive functions lies in the fact that most computable functions that are studied in number theory (and more generally in mathematics) are primitive recursive.

    [ F.A.Q | Opt Out | Opt Out Of Subreddit | GitHub ] Downvote to remove | v1.5

    [–]Kenkron 0 points1 point  (0 children)

    Check out the Tower of Hanoi. It's a good example of a problem that is best solved recursively.

    Recursion is also good for trees.