pic
Personal
Website

4c. Conditional Statements

PhD in Economics

Introduction

In many real-world applications, programs may need to execute different operations depending on the input provided. To handle these scenarios effectively, programs must then be able to adapt the code accordingly. Conditional statements provide exactly this capability, allowing for contingent executions of code blocks.

Each code block of a conditional statement is referred to as a branch. Based on the number of branches, there are three types of conditional statements:

  • if-then statements, which consist of a single branch. They run a specific operation only if a condition is met, with no operation performed otherwise.

  • if-else statements, which consist of two branches. They run a specific operation if a condition is met, and another if the condition isn't satisfied.

  • if-else-if statements, which consist of three or more branches. They comprise a series of conditions, with each branch executing a different code block.

Next, we cover each in depth. The presentation builds heavily on the logical operators introduced in the previous section. If you haven't read it, I highly recommend doing so before continuing.

If-Then Statements

If-then statements execute an operation when a condition is met, and do nothing when the condition isn't satisfied. There are three ways to construct these statements: using the if keyword, and another two based on the logical operators && and ||.

Below, you'll illustrate the syntax for each form. The examples rely on the println function, which displays the text included as its argument in the REPL.

x = 5

if x > 0
    println("x is positive")
end

Output in REPL
"x is positive"

x = 5

(x > 0) && (println("x is positive"))

Output in REPL
"x is positive"

x = 5

(x ≤ 0) || (println("x is positive"))

Output in REPL
"x is positive"

If-then statements imply that no action would've been taken if, for instance, we had used x = -1 as a condition. It's only when x > 0 that println is executed. The approach based on theif keyword is somewhat verbose for simple conditional statements. However, it also offers the most flexibility, making it ideal for complex conditional statements.

For simple statements, && and || are more concise, helping us keep the code streamlined. Specifically, && executes an operation if the condition is true, whereas || instead does it when the condition is not satisfied. In fact, || is equivalent to && with its condition negated. This can be appreciated in the example above, where we obtain the same results by flipping the condition x ≤ 0 to !(x > 0).

Remark
Note that these operators behave like if-then statements because they combine a condition with an operation. This is different from using && and || for conditions, where all operands must be Bool values.

If-then statements with || are often used to handle errors, or more generally to alert us about an issue. This requires combining || with the function error, which immediately interrupts the script's execution and displays the message provided in its argument. For instance, if you define a function foo(x) that only accepts non-negative values for x (e.g., the logarithmic function), you could include x > 0 || error("x must be positive") as the function's first line. Then, if you run foo(x) with a non-positive x, the function will stop and display the error message "x must be positive" in the REPL.

If-Else Statements

For their part, if-else statements execute an operation when a condition is true, executing another operation when the condition is false. There are two forms to write these statements.

The first method is the most flexible, and is based on an extension of if through the keyword else. The second method instead relies on the so-called ternary operator, which requires the keywords ? and :. Its syntax is <condition> ? <operation if true> : <operation if false>, and is referred to as the ternary operator since it's the only operator taking three arguments.

We illustrate the syntax of each approach below.

x = 5

if x > 0
    println("x is positive")
else
    println("x is not positive")
end

Output in REPL
"x is positive"

x = 5

x > 0 ? println("x is positive") : println("x is not positive")

Output in REPL
"x is positive"

An alternative for defining if-else expressions is provided by the function ifelse. This takes three arguments: a condition, an expression to be executed if true, and another expression to execute if false. [note] The function ifelse doesn't behave as a short-circuit operator. This means that all statements are evaluated, regardless of whether the condition is true.

Expressing an if-else statement through a function enables broadcasting. This is particularly helpful when defining vectors with elements that depend on a condition, as demonstrated below.

x = [4, 2, -6]

are_elements_positive = ifelse.(x .> 0, true, false)

Output in REPL
julia>
are_elements_positive
3-element BitVector: 1 1 0

x = [4, 2, -6]

x_absolute_value = ifelse.(x .≥ 0, x, -x)

Output in REPL
julia>
x_absolute_value
3-element Vector{Int64}: 4 2 6

Remark
Notice that broadcasting ifelse requires broadcasting both ifelse and the condition. The first example, for case, would throw an error if we only broadcast ifelse, as in ifelse.(x>0, true, false). This is because x > 0 would attempt to check if the entire vector is positive, which is an operation undefined in Julia.

If-Else-If Statements

So far, we’ve analyzed conditional statements with up to two operations: one if the condition is met, and another if it isn’t. However, this structure imposes some limitations when dealing with multiple alternatives. Basically, by only allowing for two possible outcomes, as it requires nesting multiple if and else statements to add new conditions.

To simplify this process, we can use the elseif keyword to extend the if and else approach. This is illustrated below.

x = -10

if x > 0
    println("x is positive")
elseif x == 0
    println("x is zero")
end

Output in REPL

x = -10

if x > 0
    println("x is positive")
elseif x == 0
    println("x is zero")
else
    println("x is negative")
end

Output in REPL
"x is negative"

The examples showcase the flexibility provided by the approach. For instance, the first example shows that elseif eliminates the need to specify what occurs in each scenario: it performs an action if x is positive, another action if x is zero, but does nothing otherwise. This contrast with the use of if and else, which requires structuring code to cover all possibilities exhaustively. Likewise, the second example demonstrates that if, else, and elseif keywords can be combined in multiple ways to achieve the desired program behavior.