The Wings programming language has this feature called struct expansion where the last parameter of a function is implicitly allowed to use inline field init syntax, e.g.
foo(1, 2, .a = 3, .b = 4);
is syntax sugar for
foo(1, 2, .{ .a = 3, .b = 4 });
.
This got me thinking that something like this can be used to implement default arguments, varargs, keyword arguments, and parameter splatting in one fell swoop.
It can take 3 forms:
- varargs
// varargs must be last parameter
fn foo(i: i32, inline args: []string) {}
foo(1, "a", "b");
foo(1, inline []string{ "a", "b" });
@call(.auto, foo, .{ 1, []string{ "a", "b" } });
- keyword args (with optional default values)
const Vec2 = struct {
x: i32,
y: i32 = 0,
};
// keywords must be either first or last parameter
fn foo(i: i32, inline pt: Vec2) {}
foo(1, .x = 2);
foo(1, inline Vec2{ .x = 2 });
@call(.auto, foo, .{ 1, Vec2{ .x = 2 } });
- keywords + varargs
// keywords must be first parameter
// varargs must be last parameter
fn foo(inline pt: Vec2, i: i32, inline args: []string) {}
foo(.x = 2, 1, "a", "b");
foo(inline Vec2{ .x = 2 }, 1, inline []string{ "a", "b" });
@call(.auto, foo, .{ Vec2{ .x = 2 }, 1, []string{ "a", "b" } });