In C & many languages inspired by it, an if statement looks like this:

if (condition) {
    do_something();
}

however, languages like Go let you do this:

if condition {
    do_something();
}

A rust dev mentioning go in a non-negative light? Is the world ending???

Not yet, cat. I’m just worldbuilding

The second form is definitely a bit more convenient to type, but the first form exists for very good reasons, and is even hidden away in the latter.

We’re not blind, we can definitely see that Go’s version is very different.

You may think that, dear reader, but they’re actually not as different as you may think.

And it all comes down to

Parsing

The crux of the issue is parsing - the way the syntax of the programming language is morphed into a form which has meaning

Any self-respecting compiler or interpreter won’t do this on the raw text, but will lex it first and parse the result of that. But it doesn’t make much of a difference for this post. Maybe I’ll talk about that in the future.

An if statement is the keyword if, followed by an expression forming the condition, followed by a statement for the body

Crucially, a braced block is actually a single statement masquerading as multiple for this simple explanation, but it doesn’t have to be

While parsing, we need some way to recognise when the expression ends and the body begins. While it is possible to do this by attempting to parse an expression, then falling back to parsing a statement if that fails, a much easier approach is to add a delimiter.

This is what Python does for all its ““blocks””:

def foo(x):
    if condition:
        match x:
            case 5:
                print("Five")

Complete with unfathomable amounts of rightward drift!

It’s also exactly what C does. Just instead of a colon for the delimiter, it uses a right paren.

The only reason the left paren is there is to balance out the parenthesis, because this looks really ugly

if condition)
    do_something();

Even When Hidden, It’s Still There

Despite seeming different, the Go way is actually basically the exact same. Just, instead of parenthesis, the delimiter used is an opening brace!

That’s why Go doesn’t allow you to do this, for example

if condition
    do_thing();

while C allows it just fine. Without the opening brace, the Go parser doesn’t know when the condition ends and just keeps going untill it drops a

syntax error: unexpected semicolon, expected { after if clause

So the answer is that compiler writers took the easy way out

Ehh, more like parsing is bloody hard, so why make it even harder for yourself when the user can type 2 characters & make your life so much simpler.