Why does Godot need a colon after an if stement?

Godot Version

4.2.1

Question

Sorry for the newb question, but… with a program like this:

if (a==2)
    print("a is 2")

Godot will complain because I forget the colon at the end of the if

Error at (1, 14): Expected ":" after "if" condition.

But if it knows there should be a colon, why does it need it? Why not take the newline to be the end of the if?

edit: I guess I would really need a dev to answer this!

1 Like

It depends on language, different languages has different styles

1 Like

It’s a syntax requirement for the language. There is no other “why”.

1 Like

I already made my own languages, and the reason it needs a column is so we can know the end of the line, aka the end of the token. It could made so we don’t need it altogether but it would make the syntax inconsistent and the code less readable.

It’s usually why, otherwise languages like Python would have such features.

4 Likes

Requiring a colon for ‘style’ isn’t really an answer to my question - why is it required

Yes, it’s a syntax requirement, but why?

No, the colon is not required to know where the end of the token is, as there’s a new line, so why is it required by the parser?

I think the colon need because to start with a extra tab on next line

1 Like

You don’t need a new line though, this is valid:

if foo: bar()
3 Likes

it is required for one-liner if statements

func _process(delta: float) -> void:
    velocity.y += gravity * delta
    if no_input: return
1 Like

No, that isn’t the case. The parser complains there’s no colon because the line starts with ‘if’.

Sure, then the colon isn’t required unless you want to make a one-line statement.

Sure, a colon can be used to create a one-liner. But (as far as I can see) there’s no reason to require it at the end of a line.
Sure, allow it, for “consistency” (although getting rid of all colons at the end of lines would be consistent), but I come back to my observation that if the parser knows there should be a colon, there’s no reason to make it mandatory.

You are right, it is a arbitrary language design decision. I would love if they removed both the colon and the ability to create one-line ifs and funcs. It’s a small change that doesn’t affect much but requires a major version change as it would break all existing gdscripts.

It’s got pros and cons like any other decision, and a history to support.

Well I think using the colon for one-liners is fine. It’s sort of the opposite of using \ to split a line.
But I agree, forcing colons at the end of certain lines does seem arbitrary, which is why it gets my goat when I’m told off by the editor for leaving it out!
Colons at the end of lines could be simply made optional, which would maintain backwards compatibility.

1 Like

It’s not just arbitrary though, it helps with parsing, having distinct, specific tokens in specific positions helps greatly with making specific parsing points that handle depth

The colon itself isn’t even arbitrary in the use here, it’s been used for this purpose in programming for a long time, to introduce a new section or clause

1 Like

It’s important to view error messages as advice rather than antagonistic. You are working with the program and it wants to work with you, only it speaks a different language.

Call me crazy, or a compiler engineer, but as an optional that’s more mental load for developers to process, especially in team environments or helping on the forum. And it’s significantly more complexity for the compiler to handle with very little benefit. I know I don’t want to implement it, bias against it aside.

1 Like

I’m confused as to why this frustrates you? Why are you leaving it out? Are you actively fighting the language by refusing to use it as it’s designed? Or do you just forget them?

1 Like

I think it’s just to make sure you mean what you say and say what you mean: What does this mean? With a “:” this would be legal. Without it is legal, but maybe you left out the and and \

	var xx=0
	if 1==1 
		xx==3
1 Like

TLDR; being forced to manually add a colon when the parser already knows there should be a colon is intrinsically pointless labour.

I have 40 years programming experience, so I understand tokens, parsers etc. I understand { }, if /then/endif etc etc. But, so far, I haven’t got in the habit of using a : on the end of an if statement in Godot, and it annoys me when I forget it and the editor throws an error. Let me explain why:

In C, the tokens are needed because whitespace is ignored, ie

if (a==2)
{
     printf("inside if");
}
printf("after if");

is equivalent to

if (a==2) { printf("inside if"); } printf("after if");

But Godot uses EOL and indentation to replace tokens. Comparing GDScript to C:

if a==2:                   # : is equivalent to {
     print("inside if")    # EOL implies ;
                           # change in indentation implies }
print("after if")          # EOL implies ;

So, why doesn’t GDScipt use if + EOL to imply { ? ie

if a==2                    # if + EOL implies {
     print("inside if")    # EOL implies ;
                           # change in indentation implies }
print("after if")          # EOL implies ;

@gertkeno argues that requiring the parser to identify ‘if’ so that EOL implies ‘{’ would add more complexity, but the parser must already do this to be able to complain about the missing colon!

I hate using indentation to denote scope, but it grates even more that, even though I must get the indentation right I also have to use a token, but only at the top of the block. For goodness sake, use indentation or tokens but not both!

@wyattbiker makes a valid point that without the colon there’s room for error. Yes, that’s why languages have used tokens for 50+ years. Using whitespace and EOL as tokens is A Bad Idea because it means you can easily slip up. For example, instead of

if (a=2):
    print("a was two")
a=5
print("a is 5")

you could end up with

if (a=2):
    print("a was two")
    a=5
print("a is 5")

(which is far more likely than missing “and \” off the end of an if statement) but GDScript uses whitespace and EOL as tokens and to denote scope, and we have to live with that. The problem is that it doesn’t use them consistently.

But mostly I am annoyed because the parser knows there should be a colon, so there is no need for the colon, yet I am forced by an inanimate object to manually add it. It’s not “advice”, it’s an intrinsically pointless task I am forced to do - the definition of punitive labour.