# Conditional Statements

For a programming language to be turing complete, it requires some form of branching statements and decision-making mechanisms. Conditional statements such as if and switch statements can be used to determine whether to execute a particular piece of code.

### If Statement

If statements are the simplest and most commonly used conditionals that allow programmers to conditionally execute or skip a line or block of code. The simplest form of an `if` statement consists of the if keyword followed by a condition expression enclosed in parentheses, which may look like this:

```typescript
if (x < 0) println("x is not a natural number.")
```

This evaluates the expression inside the parentheses, and if true, executes the statement following the parentheses. Instead of a single-line statement, a block of code can also be used.

```typescript
if (x != 0) {
    println("x is not zero, it is possible to be used in division.")
    y = 1
    println(The result is: ${y / x})
}
```

An `else` branch may follow the if branch to specify a block of code that executes if the condition evaluates to false.

```typescript
if (x > 0) {
    println("x is a positive number.")
}
else { 
    println("x is not a positive number.")
}
```

It is also possible to nest an if statement inside another, though it becomes tricky if blocks are not used to wrap the code inside the `if` or `else` keywords. Consider the following code:

```typescript
if (x > 0)
    println("x is a positive number.")
    if (x < 0)
        println("x is a negative number.")
    else 
        println("x is zero.")    
```

Lox2's grammar dictates that the else branch is always paired with the nearest if branch, so the code above is unambiguous to the parser and works as intended without surprises. However, the language guidelines recommend against writing such unreadable code and recommend using blocks instead in most cases unless the intent is clear.

Although Lox2 does not have a dedicated `elseif` keyword like some C-family languages, writing another if statement directly following the `else` keyword can achieve the same behavior. &#x20;

```typescript
if (x > 25) {
  println("You guessed a number too big.")
} 
else if (x < 25) {
  println("You guessed a number too small.")
} 
else {
   println("Congratulations, you guessed the correct number!")
}
```

If statements are not expressions and therefore do not evaluate to a value. If passed as an argument to functions or methods, the result of the evaluation is simply `nil`. There is a plan in future versions of Lox2 to convert if statements into expressions, where the last expression in each branch becomes the return value.

### Switch Statement

Lox2 also supports switch statements like most C-family languages. A switch statement consists of the `switch` keyword, an expression, and a block. Inside the block, there may be one or multiple `case` branches and optionally a `default` branch if none of the cases match. If the evaluated expression matches a case, the `case` block is executed. Otherwise, the `default` block is executed if present.

```typescript
val fruit = "banana"
switch (fruit) {
    case "apple":
        println("Apples are $1 per lb.")
    case "peach":
        println("Peaches are $1.5 per lb.")
    case "orange":
        println("Oranges are $1.25 per lb.")
    case "banana":
        println("Bananas are $0.6 per lb.")
    default:
        println("Sorry there is no data found.")    
}
```

Unlike many C-family languages, Lox2's case blocks do not exhibit fall-through behavior, so there is no need to insert the `break` keyword at the end of a case block. Additionally, the expression inside a case block may be any valid expression, not just literal constants as in C. The following code is valid in Lox2:

```typescript
using clox.std.util.Date

val x = 5
switch(x) { 
    case Date.now.year:
       println("The value matches current year.")
    case Date.now.month:
        println("The value matches current month.")
    case Date.now.day:
        println("The value matches current day.")
    default:
        println("The value does not match anything.")
}
```

Note: In future versions of Lox2, the switch statement will be deprecated and replaced by the match expression or statement that supports structural pattern matching.

### Control flow with Logical Operators

The logical operators `and`, `or` exhibit short-circuiting behavior, meaning that the second operand may or may not be evaluated depending on the first operand. For the `and` operator, if the first operand evaluates to false, it immediately returns false without evaluating the second operand. For the `or` operator, if the first operand evaluates to true, it immediately returns true without evaluating the second operand.

This short-circuiting behavior makes logical operators more efficient. Another side effect is that they can be used for control flow similar to an if statement. For example, the following two code snippets are equivalent:

```typescript
var x = 0

// using if statement
if (x == 0) x = x + 1

// using logical operator
x == 0 and (x = x + 1)
```

Such clever code can be elegant at times but should be used with caution, as overusing this coding style can make the program unreadable.
