Start learning free

LESSON 81 OF 414 · CONDITIONAL STATEMENTS

Combining Logical Operators in Scala

Lesson Read the full explanation

Sometimes we need to combine logical operators to evaluate more complex conditions. For example:

7 >= 10 && (5 == 7 || 9 < 12) // Evaluates to false

Notice that we used parentheses to group 5 == 7 and 9 < 12 together. The computer interprets this line of code as condition1 && condition2 where:

  • condition1 is 7 >= 10, which is false
  • condition2 is (5 == 7 || 9 < 12), which is true
At least one of condition1 and condition2 is false, so the entire condition is false.

It is very important to use parentheses to tell the computer how to group the conditions together. If we change the parentheses in the example above to:

(7 >= 10 && 5 == 7) || 9 < 12 // Evaluates to true

Now the computer interprets this line of code as condition1 || condition2 where:

  • condition1 is (7 >= 10 && 5 == 7), which is false
  • condition2 is 9 < 12, which is true
At least one of condition1 and condition2 is true, so the entire condition is true.

Assignment
Follow the Coding Tutorial and let's combine some logical operators.


Hint
Look at the examples above if you get stuck.


STEP 1 OF 2
    Ctrl + Enter to check

    SCALA · CONDITIONAL STATEMENTS

    Combining Logical Operators in Scala, explained

    Why combine operators

    Real conditions are rarely a single comparison. You might need "this flag is set, or the value is in a certain range". Scala lets you mix && (AND), || (OR) and ! (NOT) in one expression. The result is still one Boolean, and it is evaluated in a fixed order.

    Grouping with parentheses

    Parentheses decide which parts are evaluated together. Compare these two expressions, which use the same pieces:

    7 >= 10 && (5 == 7 || 9 < 12)   // false
    (7 >= 10 && 5 == 7) || 9 < 12   // true
    

    In the first line the program reads condition1 && condition2, where condition1 is 7 >= 10 (false) and condition2 is (5 == 7 || 9 < 12) (true, because 9 < 12 is true). AND needs both sides to be true, so the result is false.

    In the second line the program reads condition1 || condition2. Now condition1 is (7 >= 10 && 5 == 7) (false) and condition2 is 9 < 12 (true). OR needs only one true side, so the result is true. The same four comparisons give opposite answers, purely because of where the parentheses sit.

    Precedence without parentheses

    When there are no parentheses, Scala applies a fixed order: comparisons first, then &&, then ||. In other words, && binds tighter than ||, as multiplication binds tighter than addition.

    println(true || false && false)     // true || (false && false)
    println((true || false) && false)   // false
    
    true
    false
    

    The first line is true because false && false is evaluated first, giving false, and then true || false gives true. Adding parentheses in the second line changes the order and the answer.

    You can rely on this order, but it is kind to the reader to add parentheses anyway when AND and OR meet in one condition. They cost nothing at run time and make the intended grouping obvious.

    Evaluation stops early

    Both && and || evaluate left to right and stop as soon as the answer is known. false && x is false and true || x is true, whatever x is, so x is not evaluated. This is useful for guarding a check: in list.nonEmpty && list.head > 0, the call to head only happens when the list has an element.

    The lesson's exercise

    The code starts with these values:

    val specialStudent: Boolean = false
    val age: Int = 23
    

    A student is let in if they are a special student, or if their age is between 18 and 30, both ends included.

    1. Write the age check. "Between 18 and 30" needs two comparisons joined by AND: age >= 18 && age <= 30. Both bounds are inclusive, so the comparisons use >= and <=.
    2. Join it with the special-student check. Put specialStudent on the left of || and the parenthesised age check on the right. The parentheses are not required, but they show the grouping. Print "Let him in!" when the condition holds.
    3. Add the else. It prints "Not allowed" for everyone who fails both checks.
    val specialStudent: Boolean = false
    val age: Int = 23
    
    if (specialStudent || (age >= 18 && age <= 30)) {
        println("Let him in!")
    } else {
        println("Not allowed")
    }
    

    With the starting values, specialStudent is false, but age >= 18 && age <= 30 is true for 23, so the program prints Let him in!. With age = 40 both sides are false and it prints Not allowed. With specialStudent = true and age = 40 the left side alone is enough, and it prints Let him in!.

    Common mistakes

    • Writing a range as one chain. 18 <= age <= 30 does not compile in Scala. Use two comparisons joined by &&.
    • Using OR for a range. age >= 18 || age <= 30 is true for every age, since each number is at least 18 or at most 30.
    • Missing parentheses around a mixed condition. Without them, a || b && c means a || (b && c), which may not be what you intended.
    • Off-by-one bounds. Using > and < would reject ages 18 and 30.

    Key takeaways

    • Comparisons are evaluated first, then &&, then ||.
    • Parentheses override that order, and the same pieces can give opposite results.
    • Check a range with low <= x && x <= high.
    • Both && and || stop evaluating as soon as the result is known.
    Keep going with ScalaAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free