4

I have made a dependency injection module. It uses a hack I discovered with default parameters. function (x = SomeDependency) {}. SomeDependency is not defined, but I can parse its toString (same for class constructors, arrow functions and terse object methods). It's not meant to be supported in the browser, only in Node.

My question: I could not find any documentation on whether arguments are lazily evaluated, does any specification/documentation on this exist? Or is this simply undefined behaviour?

Update:

What I am doing is using undefined default parameters (as in the example above), and parsing the toString of the function/class to find out what they are, then calling the function or newing up the class with injected arguments.

user3654410
  • 464
  • 3
  • 13
  • How do you mean 'evaluated'? As for the actual expressions put in the parens, they have to be evaluated completely before the function is called, as demonstrated by @naomik. Though you might be wondering about the lazy evaluation by the JS engine itself, whether there is any difference between using an argument in a function and leaving it unused? Now I am, and I cannot answer that. – Aurel Bílý Jun 17 '16 at 19:23
  • "manually parsing the toString of the function/class..." ... :( – Mulan Jun 17 '16 at 21:19
  • naomik: Do you have any other option? :P I'm all ears? And I do agree whole heartedly with the :( ! – user3654410 Jun 17 '16 at 21:40
  • 1
    The are not default arguments, they are default initialisers of parameters, and they are not lazily evaluated but just conditionally - whenever the argument is `undefined`. – Bergi Jun 17 '16 at 21:51
  • @Bergi Sweet, I know my terminology was a bit off. But in that case this should work just fine. If you make an answer out of that, I will mark it as the answer to my question. – user3654410 Jun 18 '16 at 00:18

2 Answers2

6

Are javascript arguments lazily evaluated?

No. JavaScript uses applicative order evaluation

This is very easy to test too

var foo = ()=> (console.log('foo'), 'foo');
var bar = ()=> (console.log('bar'), 'bar');
var bof = (a,b)=> console.log('bof',a,b);

bof(foo(), bar());

Notice you will see "foo" and "bar" appear in the log before bof is evaluated.

This is because foo and bar are evaluated first before the arguments are passed to bof

Mulan
  • 129,518
  • 31
  • 228
  • 259
  • I am watching you edit your answer more and more, an interesting show. ;) – Aurel Bílý Jun 17 '16 at 19:26
  • 2
    @AurelBílý I gave the short answer first and after re-reading it decided to expand upon some points to clear things up a little bit. – Mulan Jun 17 '16 at 19:32
  • Just curious: Is the printing order of `console.log` guaranteed to be identical to its invocation order? It's probably true for stack snippets anyway... – le_m Jun 17 '16 at 21:10
  • [console.log is not standardized](http://stackoverflow.com/a/23392650/633183). If you're worried about whether the console is jumbling up the order, you can always use other means to gather the values before displaying them. – Mulan Jun 17 '16 at 21:18
  • Thanks for the answer! I should probably read some more SICP :P – user3654410 Jun 17 '16 at 21:26
  • And a +1 btw. I didn't mark it as the answer because it's not really what I was asking for. (though that's probably more on me than it is on you!) – user3654410 Jun 17 '16 at 21:45
  • @user3654410 is SICP something you're reading? Or is that something you saw me reference in other answers? – Mulan Jun 17 '16 at 21:55
5

Are arguments lazily evaluated?

No, everything in JavaScript is eagerly evaluated (if you excuse short-circuit evaluation of logical operands).

Specifically, the default initialisers of parameters are not evaluated when the parameter is used, they are eagerly evaluated when the function is called. They are however evaluated conditionally - whenever the argument is undefined, pretty much like the statement in a if clause would be.

Does any specification/documentation on this exist?

Yes, JavaScript evaluation order is specified in the ECMAScript standard (current revision: http://www.ecma-international.org/ecma-262/7.0/). There is hardly any undefined behaviour.

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375