Godot-proposals: Add support for variadic functions (varargs) to GDScript

Created on 10 Jun 2020  路  10Comments  路  Source: godotengine/godot-proposals

Describe the project you are working on:
Reaction game
Describe the problem or limitation you are having in your project:
I can't call a function with a variable amount of arguments (if they haven't a default)!
Describe the feature / enhancement and how it helps to overcome the problem or limitation:
I could call a function with a variable amount of arguments. Of course, you should also be able to pass the argument you want, not necessarily in the given order but this is something different:look here
Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams:

func my_func(*argv):  
    for arg in argv:  
        print (arg) 

my_func("Hello", "Welcome", "to", "Godot")  

If this enhancement will not be used often, can it be worked around with a few lines of script?:
Yes, I think
Is there a reason why this should be core and not an add-on in the asset library?:
Yes, it is useful for every project.

Bugsquad edit (keywords for easier searching): python, args, kwargs

gdscript

Most helpful comment

array pack and unpack for arguments would be great, similar to Javascript / Node / PHP:

<?php

function example(...$items)
{
  foreach($items as $item){
     print_r($item);
  }
}

// Calling the function:
example(... ["a", "b", "c"]);
// or
example("a", "b", "c");

I think this would be more intuitive and you can name the packed argument however you want.

On GDScript my syntax proposal is this similar:

func example(...items):
  for item in items:
     print(item)


# Calling the function:
example(... ["a", "b", "c"]) 
# or
example("a", "b", "c")

IMHO using * or ** operators is not so obvious because that's used for multiplication, exponentiation, pointers, etc. in other languages.
In C for example, it's used for pointer dereferencing. That can lead to confusion.

Triple dot ... feels more natural and I think it doesn't have collisions with other operators. Plus, easier to type.

All 10 comments

See also https://github.com/godotengine/godot/issues/16565.

Describe the project you are working on:

Is there a reason why this should be core and not an add-on in the asset library?:

You should fill in those fields as well :slightly_smiling_face:

Is there a reason why this should be core and not an add-on in the asset library?:

I don't really understand this question haha because everything would be better to be core than an asset, wouldn't it, or do I understand nothing for that matter??

array pack and unpack for arguments would be great, similar to Javascript / Node / PHP:

<?php

function example(...$items)
{
  foreach($items as $item){
     print_r($item);
  }
}

// Calling the function:
example(... ["a", "b", "c"]);
// or
example("a", "b", "c");

I think this would be more intuitive and you can name the packed argument however you want.

On GDScript my syntax proposal is this similar:

func example(...items):
  for item in items:
     print(item)


# Calling the function:
example(... ["a", "b", "c"]) 
# or
example("a", "b", "c")

IMHO using * or ** operators is not so obvious because that's used for multiplication, exponentiation, pointers, etc. in other languages.
In C for example, it's used for pointer dereferencing. That can lead to confusion.

Triple dot ... feels more natural and I think it doesn't have collisions with other operators. Plus, easier to type.

I don't know if it would be harder to implement *kwargs if this exponentiation operator * would be added too. What do you think? I hope they won't interrupt each other if both of them will get part of gdscript.

Thumps up on this one, "splat" arguments make designing clean APIs much nicer, and allows for better metaprogramming, (Ie, "Get all thse parameters, do something funky with them and then pass them to this function", opening up various functional (ie partial applications, currying, etc) and OOP methodologies (think of how python can pass on args ,*kwargs to ancestors). Its a supremely useful construct.

Re: core vs addons. Not sure how you implement language features as plugins lol.

this would be a useful feature
but this would require implementing packing/unpacking arrays first, no?
Btw python uses tuples for that

I've come to the point in my current project where varargs would greatly improve code structure and readability.

I'd prefer the '...' over use of splats to avoid confusion as mentioned in previous comments.

I would like to point out that this would greatly help some builtin components of Godot.

For example the Tween node has a method with this signature

bool interpolate_callback(object: Object, duration: float, callback: String, arg1: Variant = null, arg2: Variant = null, arg3: Variant = null, arg4: Variant = null, arg5: Variant = null)

With the following description:

Calls callback of object after duration. arg1-arg5 are arguments to be passed to the callback.

This limits the amount of individual arguments to 5 for the callback, and bloats the signature of interpolate_callback (8 arguments is quite a lot in my opinion)

With variadic arguments, the method signature could be reduced to
```gdscript
bool interpolate_callback(object: Object, duration: float, callback: String, ...args)

Or:

bool interpolate_callback(object: Object, duration: float, callback: String, ...args: Variant[])
```
And allow for more than 5 arguments to the callback.

@Speedphoenix That said, Tween is being rewritten to have less methods that take lots of parameters: https://github.com/godotengine/godot/pull/41794

That looks great.

The tween.tween_callback(callback, params) will use an array for params, so I guess it would mostly be syntactic sugar to make that variadic

Was this page helpful?
0 / 5 - 0 ratings

Related issues

PLyczkowski picture PLyczkowski  路  3Comments

davthedev picture davthedev  路  3Comments

lupoDharkael picture lupoDharkael  路  3Comments

regakakobigman picture regakakobigman  路  3Comments

WizzardMaker picture WizzardMaker  路  3Comments