Reputation: 664
Consider the following R input:
if(TRUE){1}else{0} + if(TRUE){1}else{0}
The result is 1
, but I was expecting 2
. If I enclose each if-else statement in parentheses,
(if(TRUE){1}else{0}) + (if(TRUE){1}else{0})
then the result is 2
.
Can someone explain this behaviour?
Upvotes: 17
Views: 466
Reputation: 206207
The else
clause doesn't end till R can identify the end of the expression. In R the {}
aren't part of the syntax for if/else statements. The {}
can be used anywhere you want to possibly put multiple statements. You can also do
if(TRUE) 1 else 0 + if(TRUE) 1 else 0
The {}
aren't really meaningful. And since
0 + if(TRUE) 1 else 0
is a valid expression, R just assumes you wanted all of that for your else
clause. Normally R will end the else clause when it encounters a newline after a completed expression. This means that
if(TRUE){1}else{0} +
if(TRUE){1}else{0}
will also return the same value because the +
at the end of the first line indicates that there's more to come because a valid expression can't end in +
.
Note you can see how the expression is turned into the abstract syntax tree with the help of the lobstr
package if you are really curious.
#lobstr::ast(if(TRUE){1}else{0} + if(TRUE){1}else{0})
o-`if`
+-TRUE
+-o-`{`
| \-1
\-o-`+`
+-o-`{`
| \-0
\-o-`if`
+-TRUE
+-o-`{`
| \-1
\-o-`{`
\-0
Here we see that everything is nested in the first if
. The +
is not the main operator.
As you've done, you can use ()
or {}
to end the expression blocks explicitly
{if(TRUE){1}else{0}} + {if(TRUE){1}else{0}}
Consider also the case of
x <- 5
if(FALSE) x+1 else x+2
# [1] 7
if(FALSE) x+1 else {x}+{2}
# [1] 7
Note how the x+2
is taken all together for the else
expression. It doesn't end at the first symbol x
.
Upvotes: 15
Reputation: 10627
Is has something to to with operator affinity which determines the order of evaluation. Like math, parenthesis have a higher priority than multiplications with have a higher priority than plus and minus. The second part of the expression will never get evaluated and thus ignored resulting in 1 e.g. if(TRUE){1}else{0} + message("I'll never get printed")
. Including the parenthesis will force to first evaluate both parts seperatley and then do the plus resulting in 2.
Upvotes: 6