0

So this may be a silly question, but I've been running into this syntax mistake every now and again and can't seem to learn my lesson - because I simply don't understand why this doesn't work.

For some reason the ternary operator won't handle increments or decrements.

In the console, I found these results:

  // Firstly
var iteration = undefined; 

  // Expected increment, unexpected result
iteration = iteration == undefined ? 0 : iteration++;  //returns 0 every time

  // Then I thought maybe ternary doesn't return assignments
iteration = iteration == undefined ? 0 : iteration+=1; //increments iteration

  // Works as expected
iteration = iteration == undefined ? 0 : iteration+1;  //increments iteration

While searching for answers I found another user had the same experience with the unexpected behavior.

After more searching I found that the pre-increment works fine:

iteration = iteration == undefined ? 0 : ++iteration; //increments iteration

And came across this answer when trying to determine why the pre-increment works.

It does make sense to me why it works and post-increment doesn't - kinda. I suppose at some point the incremented value could be overwritten by the initial value if the ternary order of operations works that way, but that's all I can think of.

But really the expected behavior that I would have from the post-increment would be for iteration to be returned, and then for it to be iterated...after.

For example, this bit of code:

var bar = undefined;
//foo is set immediately and bar is incremented after it is returned
foo = bar == undefined ? bar=0 : bar++; //sets foo to be what bar was before the increment

Hopefully you have been able to bear with me here. I do understand that at this point after finding many reliable and straight forward ways to get the job done that I don't need an answer, but I'm just stumped why it works this way.

Question:

Why does the ternary operator not update the post-increment (or postfix) value returned - after it has been returned?

A comment on this answer states that

counter++ evaluates to the current value of counter, then increments it. You would be assigning the old value of counter back to counter after you've incremented.

but I still don't why the order of operations behaves this way.

Another helpful Pre-increment vs Post-increment for C++ (ironically hilarious answer)

Devin Carpenter
  • 907
  • 8
  • 21
  • why do you change the variable and assign then a value to it? – Nina Scholz Sep 09 '19 at 06:44
  • 5
    The ternary operator doesn't necessarily matter here. The same would occur with `var increment = 0; increment = increment++;`. – The issue is the assignment is given and in turn sets the original value back into the variable, effectively undoing the change by `++`. – Jonathan Lonowski Sep 09 '19 at 06:48

2 Answers2

3

Whether the interpreter runs across an expression invoking pre- or post-increment, the variable is reassigned immediately, before the expression is resolved. For example:

iteration = iteration == undefined ? 0 : iteration++;

is like

function doPostIncrement() {
  const preIncrementValue = increment;
  increment = increment + 1;
  return preIncrementValue;
}
iteration = iteration == undefined ? 0 : doPostIncrement();

Also, assignments resolve to values, so

iteration = iteration == undefined ? 0 : iteration+=1; //increments iteration

is like

function addOneToIncrementAndReturnIncrement() {
  increment = increment + 1;
  return increment;
}
iteration = iteration == undefined ? 0 : addOneToIncrementAndReturnIncrement();

It's not actually a function call, but it's not that dissimilar, in that the reassignment is done before the function resolves, or before the pre / post-increment expression resolves.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
3

In an assignment expression, the entire right hand side gets evaluated first, and its resulting value is assigned to the left hand side. That means the post increment expression needs to be evaluated and turned into a value first, which will be assigned to the left hand side afterwards. The post increment operator doesn't know what larger expression it's a part of. It will be evaluated atomically. I.e., it won't first return its value, then complete the assignment operation, and then complete the post increment operation. When evaluating the expression iteration++, the value of iteration will be incremented and the expression results in the original value of iteration, all at once.

deceze
  • 510,633
  • 85
  • 743
  • 889