Godot version:
Godot 3.1.alpha
Issue description:
Suggestion: It would be nice to be able to return void functions from gdscript like in C
func set_state(state) -> void:
state = new_state
func state_walk() -> void:
if input_running:
return set_state(PlayerState.run)
func state_run() -> void:
if not input_running:
return set_state(PlayerState.walk)
instead of
func set_state(state) -> void:
state = new_state
func state_walk() -> void:
if input_running:
set_state(PlayerState.run)
return
func state_run() -> void:
if not input_running:
set_state(PlayerState.walk)
return
Optional typing: https://github.com/godotengine/godot/issues/10630
Could also be an explicit way to request TCO
TCO?
Tail-call optimization
I'm not sure what TCO has to do with returning void though? You can easily return something via TCO.
I mean for the case where you want TCO when the function you are calling doesn't return anything.
For implicit TCO if it's in tail call position regardless then it wouldn't matter anyway. If you want explicit TCO then you'd have a new keyword in any case.
I find this confusing. What's the point of return something if you aren't returning anything? If I see such statement I assume it's a programmer's mistake who forgot the function was declared void.
I think that they're trying to to avoid an extra line.
One reason you might need it is if you are calling a function that you don't know in advance, like if it is passed into the function.
I find this confusing. What's the point of
return somethingif you aren't returning anything? If I see such statement I assume it's a programmer's mistake who forgot the function was declaredvoid.
return can be used to bounce execution out of a scope early to.. for example guard an invariant, even if the function is intended to return no value
if health < thing:
return
do_thing()
@ShawnMcCool return without an argument should already work in functions with a void return type. What won't work is return with an argument (even null).
@ShawnMcCool
returnwithout an argument should already work in functions with avoidreturn type. What won't work isreturnwith an argument (evennull).
Right. I must have made a mistake before searching out this thread. Thanks.
One reason you might need it is if you are calling a function that you don't know in advance, like if it is passed into the function.
I still don't get it. 1) How you don't know the function you're calling? (even if passed as an argument, you should have an idea). 2) If you _may_ return something, then don't declare your function as void.
For me the only purpose for this is saving one line, which I find pointless. Especially since it might cover up a legitimate mistake from the programmer.
We also have to consider that if you do something like the following:
func return_something():
return 1
func void_func() -> void:
return return_something()
The compiler would have to add an extra check to see if the function being called return something or not, so to not allow you to actually return a value from a void function.
I was thinking of something like:
func print_and_call_with_42(f):
print("Blah")
return f.call_func(42)
func do_a_thing(n) -> void:
print(n + 5)
# Usage
print_and_call_with_42(funcref(self, "do_a_thing"))
Don't know if this kind of thing is already possible. Would be even more useful to be able to store the result like
func call_timed(f):
time = ... # Get the current time
result = f.call_func(r)
elapsed = ... # Get the time elapsed
print("Time elapsed:", elapsed)
return result
func do_a_thing(n) -> void:
for i in range(1000000):
pass # Something very expensive
# Usage
call_timed(funcref(self, "do_a_thing"))
Could use it for other things too, like temporarily changing some global state while a function is called.
@raymoo this is already possible and valid. The problem would be if you had declared call_timed() to be void, because inside of it you call return result, which wouldn't make sense in a void function.
To clarify, this is not an issue to me:
func void_func() -> void:
return
func return_void_func():
return void_func()
Even if void_func() returns nothing, it's still okay to use the result (which is always null). Though it could trigger a warning.
What I don't understand is this:
func void_func_a() -> void:
return
func void_func_b() -> void:
return void_func_a()
Because in this case if void_func_a() is changed to return something, then void_func_b() will also be returning something, even though it was declared as void. I would consider it a bug, that's why I don't want to allow it.
Because in this case if void_func_a() is changed to return something, then void_func_b() will also be returning something, even though it was declared as void. I would consider it a bug, that's why I don't want to allow it.
If void_func_a was changed to return non-void, then should void_func_b trying to return void fail the type check on the return void_func_a() line?
If
void_func_awas changed to return non-void, then shouldvoid_func_btrying to return void fail the type check on thereturn void_func_a()line?
Yes, but note that such check does not exist yet, currently it simply doesn't allow anything after return if the current function is declared as void. I don't really feel the need to add this check just for saving one line break in the code.
In the future it might be useful if we wanted a feature that would allow the return type of call_timed to match the return type of the input function.
(EDIT: Statically)
In the future it might be useful if we wanted a feature that would allow the return type of call_timed to match the return type of the input function.
I don't see how this is related to the original request.
It's not, sorry. My original confusion has already been cleared up.
This feature request doesn't make any sense to me. Why would you want to pass anything into a return in a void function, and why would you want to use a void function as a value?
Most comments and reactions agree this is not needed and I haven't seen a use case for this (apart from saving an extra line break), so I'm closing this.
If anyone has a valid use case for this feature that can't be done currently (or only done with workarounds), feel free to comment and we'll reopen.
Most helpful comment
I find this confusing. What's the point of
return somethingif you aren't returning anything? If I see such statement I assume it's a programmer's mistake who forgot the function was declaredvoid.