Lesson 3 / 25
Values, Types and Expressions
Use val and var, type inference, strings and the expression-oriented style.
Everything is an expression
Declare immutable values with val and mutable variables with var; idiomatic Scala uses val almost everywhere. The compiler infers types (val count = 3 is an Int), but annotate public method signatures for clarity. Core types include Int, Long, Double, Boolean, Char, String, BigDecimal (use it for money) and Unit (like void, with the single value ()). The type hierarchy has Any at the top, split into AnyVal (primitives) and AnyRef (objects), and Nothing at the bottom (the type of throw and of empty collections). String interpolation uses s"Hi $name", f"$price%.2f" for formatting and raw for no escapes; triple quotes create multi-line strings. Crucially, almost everything is an expression that produces a value: if/else, match, blocks (the last expression is the result) and try. Methods are defined with def, and a method body can be a single expression: def gst(amount: BigDecimal): BigDecimal = amount * 0.18. lazy val defers evaluation until first use.
Values, inference and expressions
if and blocks return values, and BigDecimal keeps money exact.
val name = "Asha" // String, inferred
var visits = 0 // mutable: use sparingly
visits += 1
val price: BigDecimal = BigDecimal("49.50")
val qty = 3
val total = price * qty // BigDecimal 148.50
val label = if total > 100 then "large" else "small" // if is an expression
val discounted =
val rate = BigDecimal("0.1")
total - total * rate // a block's value is its last expression
def withGst(amount: BigDecimal, rate: BigDecimal = BigDecimal("0.18")): BigDecimal =
(amount * (rate + 1)).setScale(2, BigDecimal.RoundingMode.HALF_UP)
println(s"Hello $name, visit number $visits")
println(s"Total with GST: ${withGst(total)}") // already rounded to 2 places
println(7 / 2) // 3 (integer division)
println(7 / 2.0) // 3.5
lazy val config = loadConfig() // evaluated on first access only
def loadConfig(): Map[String, String] = Map("env" -> "dev")Prefer val
Start every declaration with val. If you find yourself needing var, check whether a fold, a recursive function or a new immutable value would express the same logic more clearly.
Quick check: What does `val label = if total > 100 then "large" else "small"` show about Scala?
- if cannot return values
- val is mutable
- if is an expression that produces a value
- Strings must be declared with var
Answer
if is an expression that produces a value — In Scala, if/else, match and blocks are expressions with results.