Take the 2-minute tour ×

I'm asking with regards to c#, but I assume its the same in most other languages.

Does anyone have a good definition of expressions and statements and what the differences are?

share|improve this question
I find the answer you chose to be ambiguous. An expression also does something-- it evaluates to a value. I provided a non-ambiguous answer. –  Shelby Moore III Dec 9 '11 at 19:36
@ShelbyMooreIII - Non-ambiguous and also wrong. The accepted answer is worded in an informal way, but that wording makes it easy to understand--and most importantly, the meaning it conveys is accurate. –  Justin Morgan Dec 13 '12 at 21:56
@JustinMorgan My answer is correct, despite the ignorance of the down-voters. The chosen answer is not accurate, because an expression also "does something"-- it evaluates to a value. –  Shelby Moore III Jan 15 '13 at 19:18
@ShelbyMooreIII - I'm sorry, but your eagerness to call others ignorant, declare documentation incorrect, and say things like "non-functional languages get this wrong" goes to your credibility. And the accepted answer you disdain is highly effective at communicating its meaning. Even if yours is accurate - and the consensus is that it isn't - I can't imagine your answer being even slightly useful to anyone who would ask this question. –  Justin Morgan Jan 15 '13 at 20:38
@JustinMorgan I am not eager to call others ignorant. There is no such word in my first comment on this issue on Dec 9 '11, which has 3 up-votes as of now. –  Shelby Moore III Jan 24 '13 at 17:12

17 Answers 17

up vote 359 down vote accepted


In the earliest general-purpose programming languages, like FORTRAN, the distinction was crystal-clear. In FORTRAN, a statement was one unit of execution, a thing that you did. The only reason it wasn't called a "line" was because sometimes it spanned multiple lines. An expression on its own couldn't do anything... you had to assign it to a variable.

1 + 2 / X

is an error in FORTRAN, because it doesn't do anything. You had to do something with that expression:

X = 1 + 2 / X

FORTRAN didn't have a grammar as we know it today—that idea was invented, along with Backus-Naur Form (BNF), as part of the definition of Algol-60. At that point the semantic distinction ("have a value" versus "do something") was enshrined in syntax: one kind of phrase was an expression, and another was a statement, and the parser could tell them apart.

Designers of later languages blurred the distinction: they allowed syntactic expressions to do things, and they allowed syntactic statements that had values. The earliest popular language example that still survives is C. The designers of C realized that no harm was done if you were allowed to evaluate an expression and throw away the result. In C, every syntactic expression can be a made into a statement just by tacking a semicolon along the end:

1 + 2 / x;

is a totally legit statement even though absolutely nothing will happen. Similarly, in C, an expression can have side-effects—it can change something.

1 + 2 / callfunc(12);

because callfunc might just do something useful.

Once you allow any expression to be a statement, you might as well allow the assignment operator (=) inside expressions. That's why C lets you do things like

callfunc(x = 2);

This evaluates the expression x = 2 (assigning the value of 2 to x) and then passes that (the 2) to the function callfunc.

This blurring of expressions and statements occurs in all the C-derivatives (C, C++, C#, and Java), which still have some statements (like while) but which allow almost any expression to be used as a statement (in C# only assignment, call, increment, and decrement expressions may be used as statements; see Scott Wisniewski's answer).

Having two "syntactic categories" (which is the technical name for the sort of thing statements and expressions are) can lead to duplication of effort. For example, C has two forms of conditional, the statement form

if (E) S1; else S2;

and the expression form

E ? E1 : E2

And sometimes people want duplication that isn't there: in standard C, for example, only a statement can declare a new local variable—but this ability is useful enough that the GNU C compiler provides a GNU extension that enables an expression to declare a local variable as well.

Designers of other languages didn't like this kind of duplication, and they saw early on that if expressions can have side effects as well as values, then the syntactic distinction between statements and expressions is not all that useful—so they got rid of it. Haskell, Icon, Lisp, and ML are all languages that don't have syntactic statements—they only have expressions. Even the class structured looping and conditional forms are considered expressions, and they have values—but not very interesting ones.

share|improve this answer
Thanks for a very clear answer. –  inspite Mar 14 '09 at 17:55
If I'm not mis-interpreting you here, you seem to claim that "(setf (third foo) 'goose)" is an expression, not a statement, both because it's Lisp, which "doesn't have statements," and because Lisp is more than a decade older than C, which was the "earliest popular language to blur the lines [between expressions and statements]." Could explain the details of that to me? –  Curt Sampson Jun 24 '09 at 18:24
@Curt Sampson, have you asked that as a separate question? –  Kelly S. French Oct 27 '09 at 23:06
If I'm not mistaken, callfunc(x = 2); passes x to callfunc, not 2. If x is a float, callfunc(float) will be called, not callfunc(int). And in C++, if you pass x=y to func, and func takes a reference and changes it, it changes x, not y. –  Gabriel Sep 23 '11 at 2:34

I would like to make a small correction to Joel's answer above.

C# does not allow all expressions to be used as statements. In particular, only assignment, call, increment, and decrement expressions may be used as statements.

For example, the C# compiler will flag the following code as a syntax error:

1 + 2;

share|improve this answer
The phrasing of the compiler error is Only assignment, call, increment, decrement, and new object expressions can be used as a statement. Probably you take a new object expression for a "call", which is OK with me (but no you got a link to MSDN). –  Jeppe Stig Nielsen May 29 '12 at 21:24
  • an expression is anything that yields a value: 2 + 2
  • a statement is one of the basic "blocks" of program execution.

Note that in C, "=" is actually an operator, which does two things:

  • returns the value of the right hand subexpression.
  • copies the value of the right hand subexpression into the variable on the left hand side.

Here's an extract from the ANSI C grammar. You can see that C doesn't have many different kinds of statements... the majority of statements in a program are expression statements, i.e. an expression with a semicolon at the end.

    : labeled_statement
    | compound_statement
    | expression_statement
    | selection_statement
    | iteration_statement
    | jump_statement

    : ';'
    | expression ';'


share|improve this answer
Incorrect logic on what a statement is. A declarative program can also execute, but a declarative program has no statements. A statement is and does "side-effects", i.e. is imperative. cf. my answer. –  Shelby Moore III Dec 9 '11 at 19:28

Rather than thinking of statements, I think of void expressions, hehe... Oh, I've been drinking too much. :)

share|improve this answer

An expression is something that returns a value, whereas a statement does not.

For examples:

1 + 2 * 4 * foo.bar()     //Expression
foo.voidFunc(1);          //Statement

The Big Deal between the two is that you can chain expressions together, whereas statements cannot be chained.

share|improve this answer
Sure statements can be chained. {stmt1; stmt2; stmt3;} is a chain, and it's also a (compound) statement itself. –  Hugh Allen Apr 8 '09 at 1:54
foo.voidFunc(1); is an expression with a void value. while and if are statements. –  tzot Dec 2 '09 at 13:57
I'm curious about the non-chaining of statements. Would something like "if (x > 1) return;" be considered to be chaining two statements together? –  Simon Tewsi Jan 29 '13 at 22:25

You can find this on wikipedia, but expressions are evaluated to some value, while statements have no evaluated value.

Thus, expressions can be used in statements, but not the other way around.

Note that some languages (such as Lisp, and I believe Ruby, and many others) do not differentiate statement vs expression... in such languages, everything is an expression and can be chained with other expressions.

share|improve this answer
And so what utility can statements have if they don't have side-effects? Answer: none. My heavily down voted answer is correct. Pure functional languages discourage side-effects, thus they discourage statements. Duh! –  Shelby Moore III Aug 25 at 6:52

For an explanation of important differences in composability (chainability) of expressions vs statements, my favorite reference is John Backus's Turing award paper, Can programming be liberated from the von Neumann style?.

Imperative languages (Fortran, C, Java, ...) emphasize statements for structuring programs, and have expressions as a sort of after-thought. Functional languages emphasize expressions. Purely functional languages have such powerful expressions than statements can be eliminated altogether.

share|improve this answer
That link is broken. Which is a shame, as I really wanted to read that! –  Matthew Schinckel Nov 28 '10 at 0:19
Fixed now, afaict. –  Conal Dec 12 '10 at 3:00

Expressions can be evaluated to get a value, whereas statements don't return a value (they're of type void).

Function call expressions can also be considered statements of course, but unless the execution environment has a special built-in variable to hold the returned value, there is no way to retrieve it.

Statement-oriented languages require all procedures to be a list of statements. Expression-oriented languages, which is probably all functional languages, are lists of expressions, or in tha case of LISP, one long S-expression that represents a list of expressions.

Although both types can be composed, most expressions can be composed arbitrarily as long as the types match up. Each type of statement has its own way of composing other statements, if they can do that all. Foreach and if statements require either a single statment or that all subordinate statements go in a statement block, one after another, unless the substatements allow for thier own substatements.

Statements can also include expressions, where an expression doesn't really include any statements. One exception, though, would be a lambda expression, which represents a function, and so can include anything a function can iclude unless the language only allows for limited lambdas, like Python's single-expression lambdas.

In an expression-based language, all you need is a single expression for a function since all control structures return a value (a lot of them return NIL). There's no need for a return statement since the last-evaluated expression in the function is the return value.

share|improve this answer
The type of a statement is the bottom type. Void is not the bottom type. See my answer. –  Shelby Moore III Dec 9 '11 at 19:07
Isn't the null type the bottom type (single value of null)? Wouldn't void be more like the unit type (but with its single value inaccessible)? –  Mark Cidade Dec 9 '11 at 22:04
If void is the return type of a function that never returns (e.g. a function that throws an error), it is the bottom type. Otherwise void is the unit type. You are correct that a statement that can't diverge, has the unit type. But a statement that can diverge is the bottom type. Due to the Halting Theorem, we usually can't prove that a function doesn't diverge, so I think unit is fiction. The bottom type can't have a value, so it can't have a single value of null. –  Shelby Moore III Dec 9 '11 at 22:40
Regarding what I said three years ago, I don't know if I still think of statements as having a void type or any type really. In the statement-based languages with which I'm familiar, only values and anything that either stores or returns a value (e.g., expressions, variables, members, and functions) can have types. I generally think of the bottom type as the empty set (no values) and so anything that doesn't exist ontologically would have this type. A null value is really a pseudovalue denoting that a reference refers to something that doesn't exist. –  Mark Cidade Dec 10 '11 at 0:57
Mark I appreciated the rationality of your response. You basically took the words out of my mouth And I hope it was clear that I admitted to you that you were correct to raise the unit point. I think we agree. I wasn't going to bother mentioning this, but it seems that some people here think I am being negative. I am just trying to be factual. –  Shelby Moore III Dec 10 '11 at 6:27

Some things about expression based languages:

Most important: Everything returns an value

There is no difference between curly brackets and braces for delimiting code blocks and expressions, since everything is an expression. This doesn't prevent lexical scoping though: A local variable could be defined for the expression in which its definition is contained and all statements contained within that, for example.

In an expression based language, everything returns a value. This can be a bit strange at first -- What does (FOR i = 1 TO 10 DO (print i)) return?

Some simple examples:

  • (1) returns 1
  • (1 + 1) returns 2
  • (1 == 1) returns TRUE
  • (1 == 2) returns FALSE
  • (IF 1 == 1 THEN 10 ELSE 5) returns 10
  • (IF 1 == 2 THEN 10 ELSE 5) returns 5

A couple more complex examples:

  • Some things, such as some function calls, don't really have a meaningful value to return (Things that only produce side effects?). Calling OpenADoor(), FlushTheToilet() or TwiddleYourThumbs() will return some sort of mundane value, such as OK, Done, or Success.
  • When multiple unlinked expressions are evaluated within one larger expression, the value of the last thing evaluated in the large expression becomes the value of the large expression. To take the example of (FOR i = 1 TO 10 DO (print i)), the value of the for loop is "10", it causes the (print i) expression to be evaluated 10 times, each time returning i as a string. The final time through returns 10, our final answer

It often requires a slight change of mindset to get the most out of an expression based language, since the fact that everything is an expression makes it possible to 'inline' a lot of things

As a quick example:

 FOR i = 1 to (IF MyString == "Hello, World!" THEN 10 ELSE 5) DO

is a perfectly valid replacement for the non expression-based

IF MyString == "Hello, World!" THEN TempVar = 10 ELSE TempVar = 5 
FOR i = 1 TO TempVar DO

In some cases, the layout that expression-based code permits feels much more natural to me

Of course, this can lead to madness. As part of a hobby project in an expression-based scripting language called MaxScript, I managed to come up with this monster line

IF FindSectionStart "rigidifiers" != 0 THEN FOR i = 1 TO (local rigidifier_array = (FOR i = (local NodeStart = FindsectionStart "rigidifiers" + 1) TO (FindSectionEnd(NodeStart) - 1) collect full_array[i])).count DO
share|improve this answer

Simply: an expression evaluates to a value, a statement doesn't.

share|improve this answer
So what does a statement do? Nothing? –  Shelby Moore III Dec 9 '11 at 19:16
It can do something, but it doesn't evaluate to anything. Ie, you can not assign the result of it to a variable, whereas you can with an expression. –  Matthew Schinckel Dec 10 '11 at 9:52
And therefor a statement must have side-effects, as my heavily down voted answer states. What other utility could a statement possibly have? Even if a NO-OP was considered to be a statement (it is only "statement" in grammar but not at the semantics layer because it is erased after parsing and semantics is what we are discussing here), it wouldn't explain what the heck the general utility of a statement is. –  Shelby Moore III Aug 25 at 6:47

A statement is a special case of an expression, one with void type. The tendency of languages to treat statements differently often causes problems, and it would be better if they were properly generalized.

For example, in C# we have the very useful Func<T1, T2, T3, TResult> overloaded set of generic delegates. But we also have to have a corresponding Action<T1, T2, T3> set as well, and general purpose higher-order programming constantly has to be duplicated to deal with this unfortunate bifurcation.

Trivial example - a function that checks whether a reference is null before calling onto another function:

TResult IfNotNull<TValue, TResult>(TValue value, Func<TValue, TResult> func)
                  where TValue : class
    return (value == null) ? default(TValue) : func(value);

Could the compiler deal with the possibility of TResult being void? Yes. All it has to do is require that return is followed by an expression that is of type void. The result of default(void) would be of type void, and the func being passed in would need to be of the form Func<TValue, void> (which would be equivalent to Action<TValue>).

A number of other answers imply that you can't chain statements like you can with expressions, but I'm not sure where this idea comes from. We can think of the ; that appears after statements as a binary infix operator, taking two expressions of type void and combining them into a single expression of type void.

share|improve this answer

Statements are grammatically complete sentences. Expressions are not. For example

x = 5

reads as "x gets 5." This is a complete sentence. The code

(x + 5)/9.0

reads, "x plus 5 all divided by 9.0." This is not a complete sentence. The statement

while k < 10: 
    print k
    k += 1

is a complete sentence. Notice that the loop header is not; "while k < 10," is a subordinating clause.

share|improve this answer
while is an expression is some languages such as Scala. You are conflating grammar with typing. See my answer. –  Shelby Moore III Dec 9 '11 at 19:12
Here is the while loop in scala: tutorialspoint.com/scala/scala_while_loop.htm The loop with its predicate and no body is not a grammatically complete sentence. It is not a full expression. You need the body to complete it as an expression. –  ncmathsadist May 8 '13 at 0:42
A while with a body is still an expression in Scala. It may also be a statement if it creates side-effects, which what my heavily downvoted answer allows (an expression can also be a statement). My answer is the only correct one. Sorry to all those readers who can't understand. –  Shelby Moore III Jun 22 '13 at 16:49

Statements -> Instructions to follow sequentially
Expressions -> Evaluation that returns a value

Statements are basically like steps, or instructions in an algorithm, the result of the execution of a statement is the actualization of the instruction pointer (so-called in assembler)

Expressions do not imply and execution order at first sight, their purpose is to evaluate and return a value. In the imperative programming languages the evaluation of an expression has an order, but it is just because of the imperative model, but it is not their essence.

Examples of Statements:


(all of them imply the advance of the line (statement) of execution to another line)

Example of expressions:


(it doesn't imply the idea of execution, but of the evaluation)

share|improve this answer
What about side effects? –  Austin Henley Sep 23 '12 at 3:20


A statement is a procedural building-block from which all C# programs are constructed. A statement can declare a local variable or constant, call a method, create an object, or assign a value to a variable, property, or field.

A series of statements surrounded by curly braces form a block of code. A method body is one example of a code block.

bool IsPositive(int number)
    if (number > 0)
        return true;
        return false;

Statements in C# often contain expressions. An expression in C# is a fragment of code containing a literal value, a simple name, or an operator and its operands.


An expression is a fragment of code that can be evaluated to a single value, object, method, or namespace. The two simplest types of expressions are literals and simple names. A literal is a constant value that has no name.

int i = 5;
string s = "Hello World";

Both i and s are simple names identifying local variables. When those variables are used in an expression, the value of the variable is retrieved and used for the expression.

share|improve this answer
I'd rather write if(number >= 0) return true; else return false; or even better bool? IsPositive(int number) { if(number > 0) return true; else if(number < 0) return false; else return null;} :) –  Mahdi Tahsildari Jul 28 '13 at 20:18

I prefer the meaning of statement in the formal logic sense of the word. It is one that changes the state of one or more of the variables in the computation, enabling a true or false statement to be made about their value(s).

I guess there will always be confusion in the computing world and science in general when new terminology or words are introduced, existing words are 'repurposed' or users are ignorant of the existing, established or 'proper' terminology for what they are describing

share|improve this answer

Here is the summery of one of the simplest answer I found.

originally Answered by Anders Kaseorg

A statement is a complete line of code that performs some action, while an expression is any section of the code that evaluates to a value.

Expressions can be combined “horizontally” into larger expressions using operators, while statements can only be combined “vertically” by writing one after another, or with block constructs.

Every expression can be used as a statement (whose effect is to evaluate the expression and ignore the resulting value), but most statements cannot be used as expressions.


share|improve this answer

Most precisely, a statement must have a "side-effect" (i.e. be imperative) and an expression must have a value type (i.e. not the bottom type).

The type of a statement is the unit type, but due to Halting theorem unit is fiction so lets say the bottom type.

Void is not precisely the bottom type (it isn't the subtype of all possible types). It exists in languages that don't have a completely sound type system. That may sound like a snobbish statement, but completeness such as variance annotations are critical to writing extensible software.

share|improve this answer
A statement need not have a side effect. For instance, in python pass is a statement. It is a no-op, and it does not evaluate to anything. –  Matthew Schinckel Dec 10 '11 at 10:01
-1 This is wrong. A statement doesn't have to have a side-effect. See section 1.5 of the C# Language Specification. Not only it doesn't specify that statements must have side-effects, but it also lists several statements that can have no side-effects. –  NullUserException Dec 10 '11 at 19:35
@NullUserException I read that section. Declaration, Expression, Selection, Iteration, and Jump statements may all create side-effects. But if there is an RT expression, then it is not a statement. I realize the specification is equating expressions with statements, but this question asked for the difference between them. So either the question has no answer, or you are taking the C# spec too literally. The top voted answer is trying to say what I did. But "does something" is meaningless. "side-effect" is the meaningful way to say "does something". We have to think, not just regurgitate. –  Shelby Moore III Dec 12 '11 at 6:34
@ShelbyMooreIII You are right. The official documentation is wrong. Marc Gravell and Jon Skeet, who are possibly the most respect C# posters active on SO outside of Eric Lippert, are wrong. I, and all the others who downvoted you and left comments explaining our position are wrong. You are right. You clearly are the only person who knows what they are talking about, since you are so much smarter than all of the rest of SO. –  NullUserException Dec 12 '11 at 7:19
Knowing the precise definition of concepts like statement, expression, cast, conversion etc. has zero impact on 99.999% of everyday programming tasks. Think about that. Also: most people don't care about Haskell and Scala. –  NullUserException Dec 12 '11 at 7:30

Your Answer

