Perhaps? But the reason I reach for recursion is so that I don't have to first produce the "wrong answer", and then modify it until it's the "right answer". The sum of 1..10 is always 55. It isn't first 0, then 1, then 3, then 6, etc.
Perhaps? But the reason I reach for recursion is so that I don't have to first produce the "wrong answer", and then modify it until it's the "right answer". The sum of 1..10 is always 55. It isn't first 0, then 1, then 3, then 6, etc.
Sums and factorials are the worst possible way to teach recursion because they look like a loop with a weird twist that adds conceptual complexity but doesn't seem to be there for any other reason.
Recursion should really be taught by application to complex nested data structures. It's a lot clearer when you apply it to structures with multiple sub-levels that can be processed identically than with a simple linear list or range.
It's even very seldomly that I even need if-statements. It's clearly a difference and I really would like to think of myself that I'm not _that_ deep into the cool aid.
This has been done with Scala, F#, Haskell and Elm.
With Rust, not only do loops feel more natural, they're very clearly the right tool.
Recursion is also producing results that are "wrong answers" although I prefer to call them partial results. Just like a loop that is producing partial results as long as it has not finished yet.
I'd also think looping is far closer than recursion to how we tend to manually calculate things (either entirely in our heads or using a pen & paper or even a basic calculator).
(Edit: looks like a number of other posters have made the same point already, but in dead/downvoted posts, not sure why...)
The issue is that recursion in software development is relatively rarely about arithmetic operation. For example, you might want to traverse a tree of objects (like a filesystem folder) to run some operation on them, etc.
In this case the intermediate information is pointers to where you are currently processing various folders in your tree structure, etc. In a loop you would have to create a data structure to hold these. In recursive function this would typically be spread in multiple frames on your stack pointing to objects in your heap.
And yes I'm very much in agreement that the real power of recursive algorithms is when working with tree-like data structures.
> is there actually any chipset with the algorithmic ability to add more than 2 numbers altogether in one operation (without having to store intermediate results)
I was just answering your question. I am not responsible for quality of your questions.
What you do is you posted a question but had something else in mind. You got an answer but that answer does not match the question you had in your mind so now you think it is ok to berate somebody for not being able to read your mind.
Perhaps? But this would be like asking if there was a chipset that can work without branching because of someone mentioning "GOTO bad".
> I'd also think looping is far closer than recursion to how we tend to manually calculate things
It's not the looping I mind, it's the mutation.
Not true. If you share your copy of:
answer = sum [1..10]
One viewer might see: answer = 3 + sum [3..10]
and another viewer might see: answer = 6 + sum [4..10].
They may be "partial results", but they are correct and equal to each other. This is different from one viewer seeing 3 and another viewer seeing 6."But can't you just hide the partial result until it's ready?"
Sure. Get rid of class fields and getters(). I'm happy to. Are you?
And yes, if you do have that exceptional case of a complex algorithm that needs to store partial results in ivars as they are required by different methods and inconvenient to pass around individually, those ivars tend to not be exposed.
In fact, you'd more likely create a separate context object that you pass around, so also not visible externally.
Cool! Then it follows:
If a result is not temporary, then it can be immutable. Properly immutable, not just final.
If a result is temporary, then it is not to be visibly external at all. Not as a field, and not via any getter.
I could live with that.
In fact, I'd say that if you're doing algorithms as objects, you're almost certainly Holding it Wrong™.
Algorithms tend to be perfectly fine contained in a method of an object.
s = 0
i = 0
// Invariant: before and after every iteration, s is equal to sum of [0..i]
// End condition: i == n
while i != n:
s += i
i += 1
// Here, i == n and so s is a sum of [0..n] because the invariant still holds
That's how loops were supposed to be thought about (and written) since the 70ies, and it's more or less equivalent to induction which is what you're supposed to use when you think about recursive functions.