GDScript: support mixing multiple variable definitions and expressions in if-statement#98335
GDScript: support mixing multiple variable definitions and expressions in if-statement#98335zjin123 wants to merge 2 commits intogodotengine:masterfrom
Conversation
bfde7e1 to
c035f99
Compare
f55af4d to
590a8cb
Compare
|
I'm not sure about the comma syntax, it's basically a weird |
Both the comma syntax and multiple definitions / conditions are borrowed from Swift (optional binding). As a Swift user, the comma syntax appears more readable than As for multiple definitions / conditions, it is mainly for static typing. While GDScript is a dynamic typing language, some people like me actually use it with static typing as much as possible. Static typing will introduce extra code. For example, consider dragging: Without static typing: Is very readable. But if one write it with static typing (maybe for performance and static checking): If only one definition / condition is allowed, the first With static typing and multiple conditions: This one requires less code lines and is as readable as the first dynamic typing one. Multiple conditions is useful for code with static typing. Code with dynamic typing perhaps do not need it at all. |
|
Still, the comma syntax should be a separate proposal and separate PR IMO. Can you split it? |
|
Sure. I close this PR for now and will reopen it when split is done. |
|
The reason of using comma here is that To fix it: The one works but requires additional parentheses. With comma syntax, it is simple: |
|
I suggest you look into the already implemented match statement guard patterns I think what makes the most sense here is something like: if var x = 1 when x != 5:
# x is not 5
if var x = randf() when x > 0.5:
# This has a 50% chance of happening, and I have the random float stored in x. |
|
I thought about this issue a bit more, and shouldn't just evaluating declarations and definitions be enough? if var x = 1, foo(x):
print(x) # x is intShould become: if foo(var x = 1):
print(x) # x is intIn this case if var x = 1 and y == 2:
print(x) # x is truex isn't really used in the conditional which means if we want to only check if y equals 2 this can be rewritten as: if y == 2:
int x = 1
print(x) # x is int The idea here is that the var x = 3 + 5 # returns 8
var y = x # returns x (8)
x = y * 2 # returns y * 2 (16)
print(var z = x + y) # prints x + y (24)The discussion in #7222 concluded that this is very problematic, but I think maybe have it give you a warning or even an error by default when writing statements like EDIT: |
UPDATE: As @KoBeWi suggested, the original PR is split into two commits. The first one implements support of variable definition in if-statement (godotengine/godot-proposals#2727). The second one introduces a new syntax for multiple variables and conditions in if-statement. For the rationale behind the second commit, please see comment and comment below.
Another attempt to implement godotengine/godot-proposals#2727 for if-statement. This patch implements two functions: allow variable definition as condition (if var n := foo():) and allow multiple conditions separated by comma in a single if-statement(if foo(), var n := bar(), n > 1:).About implementation of the second commit: the
ExpressionNode *conditionfield ofIfNodeis replaced with a list of eitherExpressionNodeorVariableNode. When parsing a single if-statement, a temporary block(SuiteNode) is created for parsing multiple conditions within and then the true block within. For an expression condition, oneExpressionNodeis created. For a variable definition, oneVariableNodeand oneExpressionNodeare created. The former one is used for generating code for initial assignment while the later one is used for testing as usual.Compilation is done like usual except that, all of the not-true-jump-address for each condition will be patched to the same starting address else/elif if any, otherwise the end address of the if statement. Thus, the
write_else()interface is changed towrite_else(int count).