3

How can I call an anonymous function recursively (from within itself)?

(function(n) {
    console.log(n=n-1);
    // Want to call it recursively here without naming any function
})(20);
bardzusny
  • 3,788
  • 7
  • 30
  • 30
Abhishek
  • 401
  • 4
  • 4
  • Why no naming? You can create a function and use callback function to have dynamic code – Siamak Ferdos May 30 '15 at 09:33
  • 1
    i agree. You *can* have self invoking functions and *still* give them names. It's not mutually exclusive, it's just rare. You could write `(function test(n){console.log(n);}(20));` – amenthes May 30 '15 at 09:34
  • 1
    What is the point of this? Is this for a challenge or something, or is there a real-world reason for why you can't name the function? There is a way of doing this (mentioned in the question linked) but performance for it isn't too quick. – Qantas 94 Heavy May 30 '15 at 09:52

3 Answers3

4

Just name it. In this context the function won't be available outside of parentheses anyway - so you won't be polluting the namespace with it.

(function recursive(n) {
  console.log(n = n - 1);
  if (n > 0) {
    recursive(n); // just an example
  }
})(20); 

//recursive(20); // won't be able to call it here...
bardzusny
  • 3,788
  • 7
  • 30
  • 30
2

From the pure theoretical standpoint, if you really want to avoid any names, you can use the "Y combinator", which is basically a way to call a function with itself as an argument:

(function (le) {
    return (function (f) {
        return f(f);
    }(function (f) {
        return le(function (x) {
            return f(f)(x);
        });
    }));
})(function (f) {
    return function (n) {
        document.write(n + " ");
        if (n > 0) f(n - 1);
    }
})(20);

Here's a good explanation on how this works.

georg
  • 211,518
  • 52
  • 313
  • 390
  • +1, probably not practical but very interesting (and actually answering the question!). Here's nice quote from the explanation: "*The frustrating thing about Y is that once you’ve derived it, **it’s totally impossible to tell what it does just by looking at it**. If you made it this far, congratulations.*" – bardzusny May 30 '15 at 10:00
  • avoid any names? what about le and f? – Nina Scholz May 30 '15 at 12:17
  • @rookie: those are function arguments, not function names. There are no function names used at all - they stay *truly* anonymous in this solution. – bardzusny May 31 '15 at 06:44
  • @bardzusny, i know, but arguments are still variables, and for avoiding one function name,`(function (d) { return (function (c) { return c(c); }(function (b) { return d(function (a) { return b(b)(a); }); })); })(function (e) { return function (n) { document.write(n + " "); if (n > 0) e(n - 1); } })(20);` you get 5 variables (in the above example only 2), to handle with. – Nina Scholz May 31 '15 at 07:43
1

You will not be able to call it without name of without using arguments.callee. However you can name a function this way:

(function repeat(n) {
    console.log(n);
    n = n - 1;
    if (n > 0) repeat(n);
})(20);
dfsq
  • 191,768
  • 25
  • 236
  • 258