-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GDScript: Add support for variadic functions #82808
base: master
Are you sure you want to change the base?
Conversation
Does this support typed arrays as well? |
Currently no. I'm not sure if we should support this, as it would make it harder to check that the number and types of arguments are contravariant. |
I understand. |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
@Blade67 Please don't bump issues without contributing significant new information. Use reactions on the first post instead. We are currently focused on the upcoming 4.2 release, which will not include this feature. After that I'm going to continue working on this feature. |
If you work just with GDScript, there are some easy workarounds regarding vararg functions. But if you're using GDExtension this is a big deal. I like to communicate with GDScript with the call function:
If I want to pass a variable number of parameters, I can't unless I create an Array. But the most annoying thing in GDExtension is that you just can't initialize arrays or Dictionaries directly, So to achieve this I need to use "append" which is a pain:
With this commit it will be like this: |
I decided to split this PR into two parts:
With this PR only you won't be able to do: func vararg_func(x: int, y: int, ...args: Array) -> void: # Rest parameter.
other_vararg_func(x, y, ...args) # Spread syntax. But you will be able to do: func vararg_func(x: int, y: int, ...args: Array) -> void: # Rest parameter.
other_vararg_func.callv([x, y] + args) Now I'm working on the spread syntax. I'm not sure if we could merge just rest parameter for 4.3 and leave the spread syntax for 4.4. But in any case, two PRs are more convenient for review. As for supporting typed arrays, in addition to the problem mentioned above, there is an obstacle that Finally, there is the question: should we introduce a new token |
I would vote in favor of waiting to merge until the spread syntax is finished. In my opinion, varargs feels like an "incomplete" feature unless there is some sort of spreading syntax. |
Regarding waiting for a spread (splat) operator before merging, I don't think a small amount of syntax-asymmetry here is a big problem given that this is a technical feature, which will have technical users. Though getting a spread operator merged at the same time as the (I found this issue looking for a simple way to generically connect to signals, since they can be emitted with any number of objects passed along to provide extra info.) |
8d017b3
to
c2634f5
Compare
Talked about in a GDScript meeting. This kind of feature would nicely fit in a 4.4 release. We need to review it first, though. cc. @HolonProduction @vnen |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The editor and tooling related stuff looks good to me aside from some nitpicks, can't say anything about the VM though.
One thing that we probably should resolve before 4.4 is that when typing the three dots we get code suggestions after the first two of them. But that's stuff for a follow up.
GDScriptParser::DataType specified_type = p_function->rest_parameter->get_datatype(); | ||
if (specified_type.kind != GDScriptParser::DataType::BUILTIN || specified_type.builtin_type != Variant::ARRAY || | ||
(specified_type.has_container_element_type(0) && !specified_type.get_container_element_type(0).is_variant())) { | ||
push_error(vformat(R"(The rest parameter type must be "Array", but "%s" is specified.)", specified_type.to_string()), p_function->rest_parameter->datatype_specifier); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really want "rest parameter" as user facing name? I feel like dropping this name without context does not really make it clear what is talked about. I think vararg parameter would be easier for users to understand. (For reference were is the name taken from?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For reference were is the name taken from?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Every time you think you know javascript 😅
I still think vararg would be a better name, since it is already used in the docs for print.
I think it should show the name. I would argue even the builtin functions should have a name attached to the rest parameter (but it's not a requirement for this PR). |
I don't know how to feel about the additional |
10abb05
to
728698f
Compare
Done: func f(...test_args):
pass
func g(...test_args: Array):
pass For native methods |
I do reiterate the sentiment that the
|
In my opinion, multiply(...) This, in my opinion, does not sufficiently convey what is being passed into the function. multiply(...factors) This makes it much clearer. However, I think this is a bit outside the scope of the PR to change. |
The documentation has already been changed as you suggest, see the comment above. Note that core and extension methods do not support rest parameter name, so hardcoded |
Production edit: closes godotengine/godot-roadmap#65