6

I have following code:

function f() {

    //...do stuff with arguments 
    //and return something...

}

f(root,
    f(child1),
    f(child2,
        f(subchild1),
        .... 
    ),
);

I want to know when the root level of 'f' is called, so I introduce a flag as an argument:

f(root, '-r',
  f(child1),
  f(child2),
  //...
)

My question is: Is there a way to know when 'f' is called on the top level "f(root,...)" without adding additional arguments?

Ullas Hunka
  • 2,119
  • 1
  • 15
  • 28
Miguel
  • 709
  • 7
  • 21
  • You could try the other way around, `F()()()()`. [Here](https://stackoverflow.com/a/51286874/3233388) is an example – Adelin Jul 18 '18 at 10:56

2 Answers2

5

No, you have no way of telling, in code within f, that its return value isn't being used to build an arguments list for a subsequent call to f. (Or indeed, that its return value is or isn't being used for any particular thing, or nothing, at all.) It's not an unreasonable question, but that information just isn't available to f.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
0

You could actually use f.caller and check if it's null; but it's forbidden in "strict mode" due to tail call optimization: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/caller

Also, it would be unreliable for your type of code: ideally, you shouldn't need such type of branching between the root and the children (see for example any tree structure implementation like the DOM or hyper-script`).

Generally, if you have a f function than returns a tree node, it shouldn't matter at what level is called. For example:

let subchild = f(subchild1)

f(root,
    f(child1),
    f(child2, subchild),
        .... 
    ),
);

That should returns the same structure of your code, but if you will check the caller it won't, since f(subchild1) will be the same as f(root).

ZER0
  • 24,846
  • 5
  • 51
  • 54
  • 1
    *"...but it's forbidden in "strict mode" due to tail call optimization..."* More generally, it's forbidden in strict mode because it's a really bad idea to be assigning the calling function to a property on the called function, not least because while **most** (overwhelmingly) JavaScript environments have only a single thread accessing a given realm, not *all* do, nor is shutting out new multi-threaded environments in the future a spec goal. :-) – T.J. Crowder Jul 18 '18 at 16:46