1

Can anyone see a problem with a recursive function written like this:

var recurse = 100;
var recursed = 0;

(function (callback){

  callback(callback);

})(function(callback){

  recursed++;

  console.log('recursed ' + recursed + ' times');

  if(recursed < recurse){

    callback(callback);

  }
});

Is there any reason why this might execute slower? Or might be considered bad practise?

Is this functional programming gone AWOL?

shennan
  • 8,669
  • 5
  • 32
  • 56
  • Is this supposed to by the Y combinator? Why do you use it in a language that supports recursion natively? Btw, a simple loop would've been the better choice - or what did you want to demonstrate with this example? – Bergi Jan 20 '14 at 00:10
  • I suppose I just prefer it visually for executing recursive functions within functions if I know the code won't be re-called. But I wanted to know if anyone thought that it might be more programmatically expensive. I appreciate that I don't need to trick JavaScript into doing something that it already does. – shennan Jan 20 '14 at 00:18
  • This isn't a Y combinator. It still hits a call stack limit. – cookie monster Jan 20 '14 at 00:21
  • @cookiemonster: The Y combinator was never supposed to get around stack limits? But you're right, this is not a [Js Y combinator](http://stackoverflow.com/q/13759207/1048572) – Bergi Jan 20 '14 at 00:25
  • @Bergi: You're right. I was mixed up. – cookie monster Jan 20 '14 at 00:35

2 Answers2

4

The core principles of functional programming are data immutability and functions being functions in mathematical sense (i.e. take value and return value without any side-effects). Those principles form referential transparency, i.e. given the same arguments a function will always return the same result.

Your function does not satisfy any of those criteria to be referred to as "functional".

The following is an example of how recursion is done in functional style:

var recursiveFunction = function( count, max ) {
  if( count < max ){
    return recursiveFunction( count + 1, max )
  } else {
    return count
  }
}

var result = recursiveFunction(0, 100) // result == 99
Nikita Volkov
  • 41,289
  • 10
  • 85
  • 162
2

Is there any reason why this might execute slower?

Yes. JavaScript is hardly tail-call-optimized. A loop would be faster.

Or might be considered bad practise?

Yes. Your example code is unreadable, it's hard to grasp what all these callbacks do.

If you want to use recursion for something like this, an IENFE (Named & Immediately Executed Function Expression) would be a better choice:

(function callback(recursed) {
     console.log('recursed ' + recursed + ' times');
     if (recursed < 100)
         callback(recursed + 1);
})(0);
Bergi
  • 513,640
  • 108
  • 821
  • 1,164
  • Cheers. Your example is clearly much better. You may want to lose the semi-colon from the end of the if statement otherwise it probably won't validate the limit. – shennan Jan 20 '14 at 00:27
  • Ooops, how did that get there? Thanks for the cue :-) – Bergi Jan 20 '14 at 00:32
  • Just to confirm, when you say `A loop would be faster`, you're referring to a for-loop? I'm traversing DOM trees, so for-loop won't suffice. The simple `if(recursed < recurse)` was just to demonstrate the element recursing as opposed to suggesting that it will only be recursing in one direction. – shennan Jan 20 '14 at 00:35
  • Yes, I meant a for-loop. Of course, for traversing trees recursion is almost necessary to make for readable code :-) I actually use that IENFE pattern quite often for DOM traversal, though some people like a normal function declaration plus an explict call better. – Bergi Jan 20 '14 at 00:45