0

I don't understand how all those f() function work, can someone explain why it prints two '1', I know it prints '1' for every '()' after f(f), but I don't know why.

function f(y) {
  let x = y;
  var i = 0;
  return () => {
    console.log(++i);
    return x(y);
  };
}
f(f)()();

And why does the 'i' doesn't increase?

Thank you.

2
  • 1
    Doesn't look like something from the "real world". More like a curiosity, a tongue-twister. I don't understand how this works and I don't mind because I'll never use this kind of twisted things in a real life scenario. Commented Nov 15, 2020 at 16:15
  • Notice that x ≡ y ≡ f. And you're calling each () => { console.log(++i); … } that is created by them only once. Commented Nov 15, 2020 at 17:15

4 Answers 4

2
function f(y) {
  let x = y;
  var i = 0;
  return () => {
    console.log(++i);
    return x(y);
  };
}
f(f)()();

is equivalent to

function f() {
  var i = 0;
  return () => {
    console.log(++i);
    return f();
  };
}
const t1 = f();
const t2 = t1();
t2();

is equivalent to

function f() {
  var i = 0;
  return () => {
    console.log(++i);
  };
}
const t1 = f();
t1();
const t2 = f();
t2();

If you did call each of t1 or t2 multiple times instead of just once, you'd increment the i from the respective closure some more. But if you instead just chain them, they call f again and initialise a new var i = 0 for a different closure.

Sign up to request clarification or add additional context in comments.

Comments

1

First, the f(y) function essentially calling y onto itself. Executing f(y) would return a new function, which when executed, would execute x(y) and return the results.

To reduce the confusion, it's just calling f(f) for each f() you executed in this example, as x === y and y === f. The important part of why i never seems to increase, is that every execution creates a new i.

What happens in behind are:

    f(f)()();
    // is same as 
    const f1 = f(f);
    const f2 = f1();
    const f3 = f2();
    // f(f) would execute first, and returns () => {
    //     console.log(++i);
    //     return x(y);  // which is same as returning f(f) in this example
    // }

Notice that executing f(f) returns x(y) which x(y) seems to be equal to f(f). Seems as it is similar in code, but different instance. Another point is that i was never carried to this new function, nor are shared to the other instances. Each f(f) creates a new i, never passed to the next function.

Comments

0

Let's name the function at line 4 , function A.
return result of function f() is function A.(at line 4 you define a function, you don't call it.)
the body of A is gonna be this and since you use those variables in an inner function, they are not gonna be exposed(i = 0, x = y = f ):

   function A(){
     console.log(++i);
     return x(y);

so what you have now is: A()().

First parenthesis: A() prints a '1' and returns result of f(f) which is function A.(the first i is exposed and a new i is created)

Second parenthesis : A is executed like I said and return another A, since there are no any parenthesis left, there is no more call.

Comments

0

You declare in f always a new i.

Instead, you could store the count into a property of the function itself.

function f(y) {
    let x = y;
    f.i = f.i || 0;

    return () => {
        console.log(++f.i);
        return x(y);
    };
}

f(f)()()();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.