If {...} Else {...}:Does the Line Break Between "}" and "Else" Really Matters

if {...} else {...} : Does the line break between } and else really matters?

Original question and answer

If we put in R console:

if (1 > 0) {
cat("1\n");
}
else {
cat("0\n");
}

why does it not work?

R is an interpreted language, so R code is parsed line by line. (Remark by @JohnColeman: This judgement is too broad. Any modern interpreter does some parsing, and an interpreted language like Python has no problem analogous to R's problem here. It is a design decision that the makers of R made, but it wasn't a decision that was forced on them in virtue of the fact that it is interpreted (though doubtless it made the interpreter somewhat easier to write).)

Since

if (1 > 0) {
cat("1\n");
}

makes a complete, legal statement, the parser will treat it as a complete code block. Then, the following

else {
cat("0\n");
}

will run into error, as it is seen as a new code block, while there is no control statement starting with else.

Therefore, we really should do:

if (1 > 0) {
cat("1\n");
} else {
cat("0\n");
}

so that the parser will have no difficulty in identifying them as a whole block.

In compiled language like C, there is no such issue. Because at compilation time, the compiler can "see" all lines of your code.


Final update related to what's going on inside a function

There is really no magic here! The key is the use of {} to manually indicate a code block. We all know that in R,

{statement_1; statement_2; ...; statement_n;}

is treated as a single expression, whose value is statement_n.

Now, let's do:

{
if (1 > 0) {
cat("1\n");
}
else {
cat("0\n");
}
}

It works and prints 1.

Here, the outer {} is a hint to the parser that everything inside is a single expression, so parsing and interpreting should not terminate till reaching the final }. This is exactly what happens in a function, as a function body has {}.

Does the line break between } and else really matters?

Note that the if else need not be in a function for it to work. It just need to be in a continuous form or in a way to be expressed as a continuous block of code. One way is being in a function. The other is to write it in one line, or even ensure that there is no line break between the if block and the else block:

x <- 1
if(x != 1) print('haha') else print('hihi')
[1] "hihi"

More blocks of statements:

x <- 1
if(x != 1){
print("haha")
} else if( x == 1){ # Note how else begins immediatley after }
print("hihi")
}

[1] "hihi"

Note that you need to know when to put the line breaks whether in a function or outside of a function. Otherwise the code might fail or even give incorrect results.

Using subtraction:

 x <- 1
x -
2
[1] -1

x <- 1
x
- 2
[1] -2

You need to know when/where to have the line breaks. Its always safe to have else follow the closing brace } of the previous if statement. ie:

  if(...){
....
} else if(...){
....
} else {
...
}

JSLint, else and Expected exactly one space between '}' and 'else' error

JSLint is based on Crockford's preferences (which I share in this case).

It's a matter of opinion which is "better".

(Although clearly his opinion is right ;)

Putting an if-elif-else statement on one line?

No, it's not possible (at least not with arbitrary statements), nor is it desirable. Fitting everything on one line would most likely violate PEP-8 where it is mandated that lines should not exceed 80 characters in length.

It's also against the Zen of Python: "Readability counts". (Type import this at the Python prompt to read the whole thing).

You can use a ternary expression in Python, but only for expressions, not for statements:

>>> a = "Hello" if foo() else "Goodbye"

Edit:

Your revised question now shows that the three statements are identical except for the value being assigned. In that case, a chained ternary operator does work, but I still think that it's less readable:

>>> i=100
>>> a = 1 if i<100 else 2 if i>100 else 0
>>> a
0
>>> i=101
>>> a = 1 if i<100 else 2 if i>100 else 0
>>> a
2
>>> i=99
>>> a = 1 if i<100 else 2 if i>100 else 0
>>> a
1

Replacements for switch statement in Python?

The original answer below was written in 2008. Since then, Python 3.10 (2021) introduced the match-case statement which provides a first-class implementation of a "switch" for Python. For example:

def f(x):
match x:
case 'a':
return 1
case 'b':
return 2
case _:
return 0 # 0 is the default case if x is not found

The match-case statement is considerably more powerful than this simple example.


You could use a dictionary:

def f(x):
return {
'a': 1,
'b': 2,
}[x]


Related Topics



Leave a reply



Submit