Statements are statements, and expressions are expressions (in Go)

I got trolled by a facetious article on Go on April 1. But it did trigger a conversation about why Go doesn’t do certain things other languages do.

The answer, in several cases, is that Go chooses to make a clear distinction between expressions and statements. It chooses not to conflate them.

By way of definition, an expression is a thing that has (returns) a value. A statement is an imperative command to do something, but itself does not have a value.

I’ll use C# by way of comparison.

Increment operators

Most C-family languages have an operator like a++, which says “increment the value of a value by 1”.

In some languages, this expression has a return value. In Go, it does not.


var a = 5;  
// prints 5 (though a is now valued at 6)


a := 5  
// syntax error: unexpected ++

To be clear, a++ is a valid statement in Go; it increments by 1. It does not, however, return a value, avoiding error-prone patterns like if (a++ == 6) { …


In C#, assignments have return values.


int a;  
Console.WriteLine(a = 5);  
// prints 5

The expression a = 5 has a return value of 5. Further shenanigans:

int a;  
Console.WriteLine((a = 5) == 5);  
// prints True

The expression (a = 5) returns a value of 5, which is then compared to 5.


In Go, assignments are statements.

a := 5  
fmt.Println(a = 6)  
// syntax error: unexpected =

a = 6 is a valid assignment statement. It is not, however, an expression (and thus can’t be evaluated and printed).


You are probably familiar with an expression like condition ? value : other. It’s generally understood as syntactic sugar for an if-else statement, with a return value.


var temp = 50;  
Console.WriteLine(temp > 30 ? "warm" : "cold");  
// prints warm


Go doesn’t have ternaries! Reason being, it’s sugar for an if-else, and if-else’s are statements, not expressions.

You may be detecting a pattern here: Go prefers orthogonality over sugar. There are classes of (human) error that result from a statement also being an expression, and Go chooses to make that class of error less likely.

Published by Matt Sherman on April 3, 2015