# Linear search using recursive function

Show 50 post(s) from this thread on one page
Page 2 of 2 First 12
• February 19th, 2014, 02:05 AM
laserlight
Re: Linear search using recursive function
Even in 2006 I would have replaced a for loop, while loop or the use of recursion to implement the linear search here with a call to std::find... except that this was an exercise specifically to practice recursion.

I don't see anything wrong (certainly not "retarded") with giving an introductory level assignment to implement linear search using recursion: it is a baby step to help students understand recursion through practice. Factorial is my own personal favourite introductory example, yet its typical recursive implementation has the same tail recursive structure that can be so easily replaced by iteration. My objection to the assignment is that -- if GrassPuppet stated it accurately -- it implies that the search key is to be hardcoded, and having students practice that doesn't seem good to me, but that's just a minor detail.

If we talking about say, what approach to choose should we be standard library authors implementing std::find (or more likely std::find_if), on the other hand, then I would pick iteration rather than recursion: it is easy to understand and straightforward to implement either way, so I might as well go for an implementation that does not rely on tail call elimination optimisation to be efficient.
• February 19th, 2014, 03:10 AM
Eri523
Re: Linear search using recursive function
Quote:

Originally Posted by superbonzo
Moreover, I'm not so sure that such optimization actually always takes place, at least so reliably to advocate its use by non experts. For example, how does tail recursion works with varying calling conventions ? how does it interact with the more and more common use of RAII making so easy to write "apparent" tail recursive functions ? what about exceptions ? ...

Some months ago, I implemented a basic recursive flood fill. It worked just fine with the small bitmaps (90x90 IIRC) it was used for in that appliction. Then I added a simple, harmless (at least seemingly) function call at the end of the function, right after the last of the four conditional recursive calls, and instantly the flood fill blew out the stack, even with smaller/less complex bitmaps I used for testing. The stack overhead of the additional function call was neclectible, and in particular since the call was made after the recursive calls, I wouldn't have expected it to have any effective impact on the stack at all (and in fact it didn't, as it turned out).

I spent quite some time pulling out my hair until I noticed that the compiler had applied tail recursion optimization to the last one of the four recursive calls, and, of course, the additional function call disabled the compiler to do that optimization, causing a massive increase in stack impact as an obscure side effect. Eventually I changed the true recursive implemtation into one utilizing a stack container, and that did the trick. Admittedly, the code looked far less intuitive after that change, though.

Though, here, I actually hit the problen due to my failure to consider that the compiler might apply tail recursion optimization to this four-fold recursion, instead of me relying on the optimization to take place, which somewhat is the exact opposite, I think it's related here.
• February 19th, 2014, 07:25 AM
OReubens
Re: Linear search using recursive function
Quote:

Originally Posted by razzle
No you're opinionated and/or have never used a functional language.

Now who's opinionated and even making unfounded assumptions.

Do I have an opinion, yes, obviously or I wouldn't be posting here in the first place.
Have I used functional languages before: yes, I'm not sure what led you to believe/assume I haven't.

And even in functional languages I'm STILL sure. Even there resursion comes at a higher cost than iteration (assuming iteration is even possible).

Quote:

maybe... and maybe I'm right in asserting it that way.
if a recursive soluition to a problem doesn't "feel" natural to students (or a programmer in general) then maybe that is the very reason why it is inappropriate.
If the instinctive / intuitive thought is to solve it by iteration, then iteration is probably the better solution anyway because it's likely to be faster and more forgiving towards stack usage.

Quote:

For example visiting the first 10 nodes of a list and generating the first 10 Fibonacci numbers both represent linear sequences that can be formulated both iteratively and recursively. Still the former would be a bad example of recursion while the latter would make sense. Why really?
Because the very definition of Fibonacci numbers is recursive (the sum of the previous two Fibonacci numbers). If the definition is recursive, then surely the solution must be too...

Whereas searching nodes in a list... I guess it depends on how you formulated the problem you might get students to think towards a recursive solution.

Quote:

My reply to dcjr84 (although he isn't likely to read it ten years after :)) was regarding tail recursion specifically. It's a special case and both GCC and VC++ replace it with iteration (in release mode optimized for speed). Yes you can rely on that.
Tail recursion is typically easy enough to spot and turn into an iterative call instead. and be sure of what you'll get without risking to blow up the stack.
Even with VC++ and optimize speed, it isn't a guarantee. And even if it is turned into an iteration it still isn't a guarantee it'll be as optimal because it'll often keep evaluating the edge/termination conditions.

And then... there are lots of compilers that don't optimize tail recursion into iteration. Or you have code that is incredibly slow in debug builds (or overflows the stack). In a student setting, you can't assume your students will only ever be working with VS or GCC, if you are touching recursion it's important to tell them about the problems associated with recursion.

If performance or potential stack overflow is important, you'd better do the conversion to iteration by hand. if neither performance or potential stack overflow is important... then it doesn't even matter if the compiler does it for you or not.

Quote:

And if you're into template metaprogramming you don't have much of a choise because recursion is your only option.
and if you have no other option, then again it doesn't matter, you have no alternative but to use what there is, that doesn't mean the template-metaprogramming-solution-with-recursion for a particular problem is necessarily the intuitive solution, and we're talking "entry level" students here, template metaprogramming is pretty advanced stuff.

I've seen quite a few elaborate template metaprogramming contortions where they end up slowing down compilation EVERY TIME because the compiler has to chew through the code, when the better solution would have been to precalculate the values and use some smart macro's to select between the values instead.
Macro's aren't ideal, but I don't want my compilations to take minutes because someone had the clever idea to calculate PI with a beast of a template metaprogramming technique (fictitional case). ANd no I'm not saying there is no place for template metaprogramming because obviously there is, but you can take it to undesired extremes.
• February 19th, 2014, 05:03 PM
razzle
Re: Linear search using recursive function
Quote:

Originally Posted by OReubens
And even in functional languages I'm STILL sure. Even there resursion comes at a higher cost than iteration (assuming iteration is even possible).

No it doesn't. From the Wikipedia entry to functional programming:

"Iteration (looping) in functional languages is usually accomplished via recursion. Recursive functions invoke themselves, allowing an operation to be performed over and over until the base case is reached. Though some recursion requires maintaining a stack, tail recursion can be recognized and optimized by a compiler into the same code used to implement iteration in imperative languages."

So in functional languages you loop by recursion and it's as efficient as iteration. Since you obviously don't know this I assumed you've never used a functional language.

Quote:

if a recursive soluition to a problem doesn't "feel" natural to students (or a programmer in general) then maybe that is the very reason why it is inappropriate.

If the instinctive / intuitive thought is to solve it by iteration, then iteration is probably the better solution anyway because it's likely to be faster and more forgiving towards stack usage.
This instinctive, intuitive and natural "feel" for iteration vs. recursion, where does it come from do you think? Lots of good things in programming is counter-intuitive and what you do instinctively is sometimes downright bad. In my view one of the most important aspects of education is to counteract preconceived "knowledge". I'm still thankful to my alma mater who had the courage to use Lisp as model language in the freshman CS course.

And what about yourself. Do you have the "feel" really? Have a look at the next quote.

Quote:

Because the very definition of Fibonacci numbers is recursive (the sum of the previous two Fibonacci numbers). If the definition is recursive, then surely the solution must be too...
The natural numbers 1,2,3,... are also recursively defined (the previous number plus 1).

Now what do you say? The definition is recursive so this sequence surely must be recursively generated just like your "feel" told you in the Fibonacci case. No? Why not?

Quote:

If performance or potential stack overflow is important, you'd better do the conversion to iteration by hand.
Your underlying assumption is that iteration is always faster than recursion and the only way to improve performance is to replace recursion with iteration.

A good counter-example is algorithms such as parallel_for where so called recursive parallelism is used to utilize multiple processor cores. Here recursion is used to improve on iteration.

So when you're using libraries such as Microsoft PPL and Intel TBB and apply what looks like typical imperative style iteration chances are there's a whole lot of recursion going on behind the scene.

---

I could go on and on but I quit here. Your argumentation doesn't hold up and you're stuck in old thinking.
Show 50 post(s) from this thread on one page
Page 2 of 2 First 12