13

This is my current code:

const fn = parameter => {
    // if, else ...
    fn(X);
};
fn(0);

Now, I can't use this approach as I need to call the function with a parameter and it must be callable recursively.

How to refactor the above arrow function to be immediately invoked and recursively callable?

Community
  • 1
  • 1
user3292653
  • 602
  • 1
  • 7
  • 25

3 Answers3

17

JavaScript provides a great solution for recursive functions: named function expressions. Hence I would recommend to use that instead of an arrow function:

(function fn(parameter) {
  // if, else ...
  fn(x);
})(0);
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • great answer. goes to show that arrow functions are not always better than named function expressions. – Reza Aug 15 '16 at 23:15
12

First, let me put the disclaimer that Immediately-Invoked-Function-Expressions (IIFE) are considered bad practice in ES6, and this is tail-recursion and personally I would change it to a for loop.

but you can always do this I guess:

((x) =>{ const fn=(p)=>{
       //whatever
       fn(q)
   }
   fn(x)
})(0)
Reza
  • 847
  • 6
  • 14
  • 2
    The article you reference doesn't say anywhere that IIFE's are "bad practice", nor does it provide any evidence for that statement. It only states that features of ECMAScript 2015 can be used as an alternative. – RobG Mar 11 '18 at 09:03
3

If you want to call recursive an lambda expression or anonymous function you need Y combinator. For more details you can read http://mvanier.livejournal.com/2897.html

For factorial it is like

var Y = (proc) => {
  return ((x) => {
    return proc((y) => { return (x(x))(y);});
  })((x) => {
    return proc((y) => { return (x(x))(y);});
  });
};

var factorial = (fact) => {
 return (n) => {
  return (n === 0) ? 1 : n * fact(n-1);
 };
};


console.log( Y(factorial)(5) );

For you code it will be like

const fn = (func)=> {

    return (parameter) => {
       // if else
       func(X);
    }
};

Y(fn)(0);
Suren Srapyan
  • 66,568
  • 14
  • 114
  • 112
  • This may be true, but this isn't self invoked. I'd like to remove the `Y(fn)(0);`. This solution seems to be a more complex but with the same result like mine. – user3292653 Aug 15 '16 at 08:00