What is the difference between Expressions and Statements in Scala
EDIT: As pointed out by @Jörg W Mittag in the comments, this answer is in fact wrong: statements do exist in the Scala spec:
Statements occur as parts of blocks and templates. A statement can be an import, a definition or an expression, or it can be empty.
I leave the original answer, as I think it is still valuable as a practical answer to the OP's question.
Orignal answer
Pedantically speaking, there is no such thing as a statement in Scala. There are definitions (such as def
and class
) and expressions. Everything that would be called a statement in other languages is just an expression.
For example, many people would call the following "line", which prints to the console, a statement:
println("hello")
In Scala, this is an expression. For example, it can be assigned to a value:
val x = println("hello")
In this case, x
is assigned the value ()
(pronounced unit
) of type Unit
.
"Theory" aside, it is common practice to call an expression that always returns ()
a statement. Which means that the above println("hello")
can also be considered as a statement.
Let us now come back to if/else
. Since everything is an expression, this if/else
is an expression:
if (cond) 3 else 5
but so is
if (cond)
println("hello")
else
println("bye")
In the latter example, though, the if/else
always returns ()
(because both println
s return ()
), and you can therefore call this if/else
a statement.
An expression is anything that can be evaluated to produce a value. When a statement is evaluated, it causes side-effects to occur but does not reduce to a value.
A useful rule of thumb is that if you can put it on the right-hand side of an assignment, it's an expression.
val x = (anything legal here must be an expression)
If you can't put it on the right-hand side of an assignment, it's probably a statement. For example, none of these are legal because the bits on the right-hand sides are statements:
val x = import scala.collection.mutable // import is a statement
val x = def someFunction() = { ... } // Function definition is a statement
val x = val y = 42 // Variable assignment is a statement
Scala, like many of the functional-first languages, has very few "pure" statements. Instead, many constructs that people think of (and refer to as) statements are expressions that evaluate to Unit
:
scala> val x = print("hello world") // a "print statement" is actually an expression
x: Unit = ()
scala> val x = for (i in Array(1, 2, 3)) println("Hello " + i) // for loops are expressions too!
x: Unit = ()
Treating "if statements" as expressions is actually quite handy:
val meal = if (hungry) Some(food) else None
tl;dr: The technical difference between a statement and an expression is that an expression evaluates to a value while a statement does not. Informally, many people use the term "statement" to refer to anything that is evaluated only for side effects, but many of those "statements" are actually expressions that evaluate to Unit
.
Statements are more imperative and expressions are more functional. If that is what you are looking for. Statements are like assignments and therefore, equated to "var" rather than "val" and they don't print out the values,you'll need a println(s"...") to get the value out of them. Whereas, expressions produce the value right away and have a type.