vlang / v

Simple, fast, safe, compiled language for developing maintainable software. Compiles itself in <1s with zero library dependencies. Supports automatic C => V translation. https://vlang.io
MIT License
35.67k stars 2.15k forks source link

Allow variadic functions with variable types #21462

Open susugagalala opened 4 months ago

susugagalala commented 4 months ago

Describe the feature

Allow defining V fn hello(i int, f f64, ...) or declaring external C functions as such.

Use Case

At the moment it seems V does not support defining/declaring a function where the variadic part has variable types, like what C and some other programming languages allow.

Instead of defininng/declaring a series of functions:

fn hello(i int, f f64, x int, y string) fn hello(i int, f f64, y string) fn hello(i int, f f64, p &Peter) ...and so on...

I'd like to only define/declare a single function:

fn hello(i int, f f64, ...)

Proposed Solution

As mentioned, allow defining V functions like fn hello(i int, f f64, ...) and declaring external (eg. C) functions as such.

Other Information

No response

Acknowledgements

Version used

V 0.4.5

Environment details (OS name and version, etc.)

Mac OS X, 10.15.7

[!NOTE] You can use the šŸ‘ reaction to increase the issue's priority for developers.

Please note that only the šŸ‘ reaction to the issue itself counts as a vote. Other reactions and those to comments will not be taken into account.

susugagalala commented 4 months ago

If it is decided that V should not allow defining V functions with variable variadic types for strong typing reasons, it is understandable. But V should at least allow declaring external C functions as such, otherwise how would I declare an external C function defined as such: void hello(int i, double f, ...) where the call could be hello(1, 2.3, a_struct) or hello(1, 2.3, "peter", 4) or hello(1, 2.3, 4, 5.6, 7) ?

thesombady commented 4 months ago

You can circumvent this by stating that the argument is a struct

struct Args {
    x int = 0
    y f32 = 0.0
    p &Person = unsafe { nil }
    d f32 = 0.0
}

fn Hello(args Args) {
    println(args.x)
}

fn main() {
    Hello(x: 1.0)
    Hello(x: 1.0, y: 0.0, p: &Person{}, d: 3.1415)
}

With this you can define the behaviour of how the function should act with different values. https://docs.vlang.io/structs.html#trailing-struct-literal-arguments

JalonSolov commented 4 months ago

You could also create a sum type. You can do variadic sum types.

thesombady commented 4 months ago

Yep something like this would work

type Arg = f32 | int | Person | string

fn Hello(arg1 Arg, arg2 Arg, arg3 Arg, arg4 Arg) {}
JalonSolov commented 4 months ago

Or, to match the request...

type Arg = f32 | int | Person | string

fn Hello(args ...Arg) {}