The definition of expression and statement - and even if there is such a thing as one or the other - is specific to a particular language and the grammar that describes it.
Well, let's go:
A statement is some 'evaluatable code'1 that does not appear in an expression context; and
An expression is code that appears in a context where the resulting value can be consumed through substitution of the expression.
{A very loose 'definition', but there is no One Language. While some languages are strict about when side-effects can and cannot occur - and code that executes without result or side-effect is useless - I do not believe discussing such is fundamental to the differences.}
For instance, let's look at printf
in C. This is a function that side a side-effect and it returns a value; usually the return value is ignored. Thus printf
can appear as both a statement
printf("Hello world!");
and an expression
if (8 == printf("Hello %s!", name)) { // ..
(A function call with a return type of void
can only appear in a statement context in C but this is imposed by the type system and not the parser.)
Likewise, take these two lines in JavaScript x = 1;
and x = (y = 2);
. x = ..
is a statement while y = 2
is an expression that yielded a value.
In both of these examples we see that it is the grammar production that determined if it is treated as statement or an expression.
In contrast Ruby can treat the 'top level' assignment as an expression:
[1].map {|x| x = 2}
Now let's take a peak a Python (2.x). In this case print
is a statement which is why these work and don't work, respectively:
print "Look ma, no parenthesis!"
x = lambda y: print "Whoops!" # invalid, print not an expression
And what about at if
constructs - are these statements or expressions? Again, it depends on the particular language. In C and Java such are clearly statements: there is no way to use such as a substitute for a value.
On the other hand, Scala (and Ruby) allows such flow control constructs to be used as expressions, although they can also appear as statements:
var emotionalResponse = if (color == "green") {
log.cheer()
new Cheering()
} else {
new Tears()
}
Whew. That is a lot - and it's not nearly comprehensive. But, back to the 'definition' which can be restated about as so, when taking the various examples above into account:
If the construct in question can occur where a value is required (eg. on the right-hand-side of an assignment, as a function argument, as input to another expression) then it can be treated as an expression; and most definitely is an expression when in such a context. If the construct appears in a location where the value cannot be accessed through substitution then it is (or rather, can act as) a statement.
1 Another class of productions to condition is declarations, such as a function declarations in C or class definitions in Java, and are arguably not statements; since the following is already so fragmented this is as much of a note that gets.
x = 1
is an expression andx = 1;
is a statement. In Ada,x := 1
is not an expression, butx := 1;
is a statement. – Fizzy