Supersedes https://github.com/godotengine/godot/issues/7223
CC @Zylann
Describe the project you are working on:
This can work on any project, but currently I want to implement a "Fallback" color if the given color is null.
Describe the problem or limitation you are having in your project:
The ternary operator can be used as a fallback, but it is...
a if a else b rather than a else b.a() if a() else b() calls a() twice.http_get() if http_get() else cached_valueDescribe the feature / enhancement and how it helps to overcome the problem or limitation:
The enhancement would be to implement an operator that simplifies this workflow. See the code example below.
Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams:
To avoid ambiguity from boolean or, I propose operator else with alternate symbol counterpart ??.
func set_color(color: Color):
modulate = color else Color.white
If this enhancement will not be used often, can it be worked around with a few lines of script?:
This will be used often. Currently, the workaround for slow or non-const function is:
var http_result = http_get()
var result = http_result if http_result else cached_value
Is there a reason why this should be core and not an add-on in the asset library?:
It would not be possible to implement this in an add-on so that the code is brief. The only simplification would be a coalescing function like
func coalesce(a, b):
return a if a else b
Even with the function, b would always be evaluated even if a is valid.
To avoid ambiguity from boolean
or, I propose operatorelsewith alternate symbol counterpart??.
I would allow only one syntax for this, so we don't have multiple ways to achieve the same thing (due to style guide complexity, among other reasons).
I'm not sure if we should go for else or ?? though.
I'm not sure if we should go for
elseor??though.
I would choose else because we went with if and else for ternary operator.
so we don't have multiple ways to achieve the same thing
What about operators or and ||?
What about operators
orand||?
|| has been deprecated in the master branch. It still works, but it prints a warning message by default :slightly_smiling_face:
The same goes for &&.
I would advocate for adding ?? as symbols.
The operator ?? is becoming ubiquitous. It has been added to C#, JavaScript, PHP, Powershell, and Swift. There are plans to add it to more languages. While PEP-505 was deferred, I think python may add it eventually. Either way, many users are coming from Unity with C# experience or have had some JavaScript experience. Now, I normally prefer english words, like else, but I would prefer symbols in this case only because I think english words are more confusing. English just doesn't capture the concept very well.
Adding ?? as symbols also makes more sense if also adding the ?. operator. (Using a word like else. would be real confusing.)
I, personally, love both ?? and ?. a lot and would love to see both added. Many godot calls can return null references and godot makes so much null by default. I feel like both are needed.
For example, getting data from a possible child node could be reduced from 6-ish lines to one with both operators in use:
var tex
var sprite = get_node("Sprite")
if sprite:
tex = sprite.texture
if not tex:
tex = load("res://...")
...
#### VS ####
var tex = get_node("Sprite")?.texture ?? load("res://...")
...
Just adding ?? alone doesn't help much in the above case. (Since we are checking for two possible nulls that can come from get_node("Sprite")?.texture. The one from get_node and the one from .texture)
Also, using else would maybe have parse confusion. Case:
var a = a if b else c else d
# Which do you mean?
var a = a if (b else c) else d
var a = a if b else (c else d)
Not saying folks should use that syntax, just that parsing it out seems problematic.
Some languages us a x ? x : y shorthand of x ?: y. Doing a similar thing would mean the shorthand in godot should be
x if else y, but, yeah, that's kinda ugly...
As a side note, it's nice if you can do multiline so it flows. In the below example, if a line ever results in null then the execution moves to the next line.
var tex_size = \
get_node("Sprite")?.texture?.get_size() ??
get_node("Sprite_2")?.texture?.get_size() ??
Vector2.ZERO
Having it flow like that makes it real easy to read and track. Pretty sure this may require ?? \ in godot, though.
Pretty sure this may require ?? \ in godot, though.
You can also use parentheses to wrap long statements without requiring \ at the end of every line:
```gdscript
var tex_size = (
get_node("Sprite")?.texture?.get_size() ??
get_node("Sprite_2")?.texture?.get_size() ??
Vector2.ZERO
)
You can also use parentheses
Oh, yeah, haha. That works.
Most helpful comment
I would advocate for adding
??as symbols.The operator
??is becoming ubiquitous. It has been added to C#, JavaScript, PHP, Powershell, and Swift. There are plans to add it to more languages. While PEP-505 was deferred, I think python may add it eventually. Either way, many users are coming from Unity with C# experience or have had some JavaScript experience. Now, I normally prefer english words, likeelse, but I would prefer symbols in this case only because I think english words are more confusing. English just doesn't capture the concept very well.Adding
??as symbols also makes more sense if also adding the?.operator. (Using a word likeelse.would be real confusing.)I, personally, love both
??and?.a lot and would love to see both added. Many godot calls can return null references and godot makes so much null by default. I feel like both are needed.For example, getting data from a possible child node could be reduced from 6-ish lines to one with both operators in use:
Just adding
??alone doesn't help much in the above case. (Since we are checking for two possible nulls that can come fromget_node("Sprite")?.texture. The one fromget_nodeand the one from.texture)Also, using
elsewould maybe have parse confusion. Case:Not saying folks should use that syntax, just that parsing it out seems problematic.
Some languages us a
x ? x : yshorthand ofx ?: y. Doing a similar thing would mean the shorthand in godot should bex if else y, but, yeah, that's kinda ugly...