2

A normal self-invoking function looks like this:

(function () {
    // Something.
})();

However, can a function somehow invoke itself in a recursive manner like this:

(function f(i, num) {
    if (num > 0) {
        console.log(i);
        f(i + 1, num - 1);
    }
})(0, 2);

but still remain anonymous?

Also

Can an ES6 arrow function invoke itself?

(a => {
    // Somehow invoke itself.
})();
dodov
  • 5,206
  • 3
  • 34
  • 65
  • 1
    No, I _don't know how_ to make a function call itself. I ask if it can call itself **while remaining anonymous**. In this case, I gave it a name `f`. – dodov Jan 16 '17 at 17:02
  • There's a difference between a function calling itself and a function being called immediately after its declaration. None of your examples involve functions calling themselves recursively. – Pointy Jan 16 '17 at 17:06

4 Answers4

6

However, can a function somehow invoke itself in a recursive manner like this

Yes. Exactly like that.

but still remain anonymous

No. You have to have a reference to a function in order to invoke it. The only way to get a reference to an IIFE is to give it a name.

The matching variable with that name is, however, only available within the scope inside that function.

Can an ES6 arrow function invoke itself?

Not unless you get a reference to it, which you can't do with an IIFE arrow function.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • I just saw another answer explaining something called [Y combinator](http://stackoverflow.com/questions/25228394/how-do-i-write-an-arrow-function-in-es6-recursively) although I didn't understand what it is. – sabithpocker Jan 16 '17 at 17:03
  • @sabithpocker - The Y combinator pattern looks seriously wonky for manually written code. Maybe useful somehow for machine generated code (like a transpiler), but not for code meant for human readability and maintainability. Much simpler to just use a name in your scope. – jfriend00 Jan 16 '17 at 17:14
  • @jfriend00 Definitely! Commented just out of curiosity :) – sabithpocker Jan 16 '17 at 18:05
1

If you run a cut-down version of your example, you get this:

(function f(n) {
  console.log(n);
  if (n) {
    f(false);
  }
})(true);

Running this:

true
false

But then if you try to call it outside of that scope, like:

f();

You get

Uncaught ReferenceError: f is not defined

Seems to answer at least part of the question.

0

To answer your first question, yes you can have a function invoke itself in the manner you described. In fact, the exact code snippet you gave runs fine. Also the this post

In answer to your ES6 question, no you cannot call an arrow function recursively (at least not in the same way, or any way I've found). The arrow function is shorthand for anonymous function syntax, and is therefore, by definition, anonymous. In order to have a named function you must create it with the function keyword

Community
  • 1
  • 1
Corbfon
  • 3,514
  • 1
  • 13
  • 24
  • _"you cannot call an arrow function recursively"_ You can. _"The arrow function is shorthand for anonymous function syntax"_ No. _In order to have a named function you must create it with the function keyword"_ No. – a better oliver Jan 17 '17 at 09:11
0

Here's a standard abstraction of recursive function definition:

const Y = (r=> r(r))(r=> F=> x=> F(r(r)(F))(x));

Here are a couple of examples of using it:

Y(fac=> n=> n<1 ? 1 : n*fac(n-1))
(5) 
// should evaluate to 120

Y(sum=> xs=> xs.length >0 ? xs[0]+sum(xs.slice(1)) : 0)
([30,2,1,4])
// should evaluate to 37
  • Welcome to SO. Please omit code only answers. Have a look here: https://stackoverflow.com/help/how-to-answer – Uwe Allner Sep 06 '17 at 11:22