Getting weird error with post-increment and brackets() - newbie

S

shamilton72

If I use the following JavaScript code:

var x=3;
var y=2;

document.write(x + y + (x++));

it gives an answer of 8 which I thought would be incorrect as the
post-increment is in brackets. However, if I change the write statement
to

document.write((x++) + x + y);

it gives in my opinion the correct answer of 9.

Is there any reason for this?

Cheers,

Sarah
 
L

Lee

(e-mail address removed) said:
If I use the following JavaScript code:

var x=3;
var y=2;

document.write(x + y + (x++));

it gives an answer of 8 which I thought would be incorrect as the
post-increment is in brackets. However, if I change the write statement
to

document.write((x++) + x + y);

it gives in my opinion the correct answer of 9.

Is there any reason for this?

You seem to believe that parentheses change the order in which
terms are evaluated. That's not the case. They simply cause the
contents to be evaluated separately, before the term is used, so:

5 + 3 * 2 is evaluated as 11,
but:
(5 + 3) * 2 gives 16

But given:

( f(x) + g(x) ) + h(x)

You can't make any assumption about which function will be called
first or last.
 
S

shamilton72

I think I understand you but even if I leave out the brackets, x++ is
post increment so I thought the increment would take place after the
execution of the staement, yet still I get:

document.write(x + y + x++); gives me 8

document.write(x + x++ + y); gives me 8 and

document.write(x++ + x + y); gives me 9. If I break it down to the
absolute basic, just using x, i.e.

var x=3;

document.write(x++); the answer given is 3, indicating x is not
incremented until after the statement is executed.

Regards,

Sarah.
 
D

Douglas Crockford

If I use the following JavaScript code:
var x=3;
var y=2;

document.write(x + y + (x++));

it gives an answer of 8 which I thought would be incorrect as the
post-increment is in brackets. However, if I change the write statement
to

document.write((x++) + x + y);

it gives in my opinion the correct answer of 9.

Is there any reason for this?

The parens are not sufficient to cause the (x++) to be evaluated first.
It is dangergous to use expressions with side-effects which rely on the
order of evaluation. You presented an example of why.

http://www.crockford.com/javascript
 
L

Lee

(e-mail address removed) said:
I think I understand you but even if I leave out the brackets, x++ is
post increment so I thought the increment would take place after the
execution of the staement, yet still I get:

No, it's not "after the execution of the statement", but after that
particular instance of the variable has been dereferenced.

so in the expression "x + x++" the value will be incremented as soon
as the second instance of "x" is used. We don't know if that will
happen before or after the first instance is used.

So the key is to avoid mixing x and x++ in the same expression.
You could substitute "2*x++".
 
S

shamilton72

I still can't figure this out. Is it a maths issue or a JavaScript
issue?

A.
var x=3
document.write(x + y + x++); gives me 8

B.
var x=3;
document.write(x++ + x + y); gives me 9.

If with basic maths you work from left to right there should be no
difference between A and B. As there are also now no inner brackets why
is it that putting x++ at the very start of a statement will give you a
different answer than putting it anywhere else, i.e. as shown above. It
seems to completely blur the lines between pre and post increment. In
other words, the only way to get an answer of 9 from A is to use pre
increment:

var x=3;
var y=2;
document.write(x + y + ++x); (9)

While this is not a programming problem I'm stuck on it's just
something I discovered so any help would be greatly appreaciated, and
remember I'm a newbie :)

Regards,

Sarah.
 
L

Lasse Reichstein Nielsen

I still can't figure this out. Is it a maths issue or a JavaScript
issue?

Is it an issue? :)
A.
var x=3
document.write(x + y + x++); gives me 8

B.
var x=3;
document.write(x++ + x + y); gives me 9.

If with basic maths you work from left to right there should be no
difference between A and B.

Basic maths does not allow side effects. Try C:
---
var x = 3;
function postIncrementX() {
var tmp = x;
x = x + 1;
return tmp;
}
document.write(incrementX + x + y);
---

This is actually how B is evaluated. You evaluate from left to
right:

evaluate x++ + x + y
1. evaluate x++ + x
1.1 evaluate x++
1.1.1 let tmp be the value of x (now 3)
1.1.2 let x = x + 1
1.1.3 the value of 1.1 is tmp (i.e., 3)
1.2 evaluate x (now 4)
1.3 the value of 1 is the sum of the result of 1.1 and 1.2 (i.e., 7)
2. evaluate y (is 2)
3. the value is the sum of the values of 1 and 2 (i.e., 9)

As there are also now no inner brackets why is it that putting x++
at the very start of a statement will give you a different answer
than putting it anywhere else, i.e. as shown above.

Because you evaluate from left to right, and evaluating x++ has
a side effect of increasing x. If you evaluate x alone before this,
it has one value, if you evaluate x alone after (to the right of),
it has a value that is one larger.
It seems to completely blur the lines between pre and post
increment.

No, but remember that the pre/post increment is pre/post only the
exact expression ++x/x++, not the entire larger expression that might
be part of.

/L
 
D

Dr John Stockton

JRS: In article <[email protected]>,
dated Tue, 12 Apr 2005 08:22:17, seen in (e-mail address removed) posted :
document.write(x + y + (x++));

Post-increment is more-or-less descended from the language C, which
originated IIRC on some form of DEC PDP machine.

The PDPs that I used had, as part of the fundamental instruction set,
some form of post-increment and pre-decrement, or /vice versa/; others
may have had both. The inc/dec are thus closely associated with reading
the value, and are not carried out at the statement level.

Parentheses affect the order of application of operators; the order of
evaluation of operands is another matter.

It's best to think of that as being NOT guaranteed, but usually left-to-
right, except when you want that when it probably is not. Or read ECMA-
262, but don't assume it's been implemented reliably.


PDP-11 fans : MOV -(PC),-(PC) ; 014747 octal
Think carefully about it!
 
R

Richard Cornford

Lasse Reichstein Nielsen wrote:
No, but remember that the pre/post increment is pre/post
only the exact expression ++x/x++, not the entire larger
expression that might be part of.
<snip>

Which brings us back to the question of the parentheses in the original
expressions:-

document.write(x + y + (x++));

- and:-

document.write((x++) + x + y);

Where the parentheses around the post increment are the ECMAScript
PrimaryExpression, with the production:-

PrimaryExpression : ( Expression )

- and the algorithm:-

1. Evaluate Expression. This may be of type Reference.
2. Return Result(1).

- In which the result of Expression is the original (pre-incremented)
value of - x - and so the value of the PrimaryExpression is also the
original value of - x -.

So the parentheses have no impact upon the situation.

Richard.
 
R

Richard Cornford

Lee wrote:
But given:

( f(x) + g(x) ) + h(x)

You can't make any assumption about which function will
be called first or last.

I think you could make assumptions about the order of execution, though
those assumptions could only be that the order of evaluation was that
described in the ECMAScript specification. Consider the following:-

var lastSt = NaN, lastSl = NaN;
function hasChangedScroll(){
if(
(lastSt != (lastSt = getScrlY())) ||
(lastSl != (lastSl = getScrlX()))
){
return true;
}
return false;
}

For the two not-equals expressions ECMA 262 says that the left-hand side
will be evaluated before the right-hand side. Thus the value of, say, -
lastSt - is determined before the - (lastSt = getScrlY()) - assignment
expression is evaluated. So the not-equals expression is true when the
values have changed since the last test, and false otherwise.

If the order of evaluation was right-hand side first then the not-equals
expression would always resolve as false as it would be comparing the
result of the assignment with the value that had just been assigned.
However, under those circumstances swapping the left-hand side for the
right-hand side would render the whole expression functional again.

In practice it is very important that it is possible to determine the
exact order of evaluation of expressions in computer language.

Richard.
 
L

Lee

Richard Cornford said:
Lee wrote:


I think you could make assumptions about the order of execution, though
those assumptions could only be that the order of evaluation was that
described in the ECMAScript specification. Consider the following:-

var lastSt = NaN, lastSl = NaN;
function hasChangedScroll(){
if(
(lastSt != (lastSt = getScrlY())) ||
(lastSl != (lastSl = getScrlX()))
){
return true;
}
return false;
}

For the two not-equals expressions ECMA 262 says that the left-hand side
will be evaluated before the right-hand side. Thus the value of, say, -
lastSt - is determined before the - (lastSt = getScrlY()) - assignment
expression is evaluated. So the not-equals expression is true when the
values have changed since the last test, and false otherwise.

If the order of evaluation was right-hand side first then the not-equals
expression would always resolve as false as it would be comparing the
result of the assignment with the value that had just been assigned.
However, under those circumstances swapping the left-hand side for the
right-hand side would render the whole expression functional again.

In practice it is very important that it is possible to determine the
exact order of evaluation of expressions in computer language.


I'm talking about the order of evaluation of terms in a
right-hand side expression:

( f(x) + g(x) ) + h(x)

It should not be important to know the exact order of
evaluation of terms of such an expression. You can
control the order by assigning the returned values to
variables in whatever order you like.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,769
Messages
2,569,577
Members
45,052
Latest member
LucyCarper

Latest Threads

Top