pglpm
pglpm

Reputation: 664

Unexpected behaviour adding two if(){}else{} constructs

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

Answers (2)

MrFlick
MrFlick

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

danlooo
danlooo

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

Related Questions