In other words, for a function f(x : T), f(.{}) is f(T()), not f(), where T() is the default constructor for type T.
If we had a function with two parameters g(x : T, y : T2) it would be g(.{}, .{}) which means g(T(), T2()), not g().
It looks like the feature exists to avoid things like:
x : really_long_type = really_long_type(), which can be replaced with x : T = .{} to avoid unnecessary duplication.
They should add default parameters to avoid this sort of thing. Maybe they ought to consider named/labelled parameters, too, if they're so concerned about clarity.
Per the article, this is the explicit form:
var gpa = std.heap.GeneralPurposeAllocator(std.heap.GeneralPurposeAllocatorConfig{}){};The fact that unacceptable parameter would fail compile time validation does not make it any more readable.
var foo = OpaqueTypeName(.{}){};
What is the . eliding?You don't know. I don't know. It's impossible to tell because the type is opaque to our understanding.
Zig is a static language without variadic parameters, so you can't make it optional in that sense. You could make the options a `?T` and pass `null` instead, but it isn't idiomatic, because passing `.{}` to a parameter expecting a `T` will fill in all the default values for you.
Arity N when you supply a value
Arity N-1 when you use the default
I can think of a few reasons
- makes function calling simpler
- faster compilation
- less symbol mangling
- makes grepping for function implementation easier
If for some reason you think you absolutely can't live without variadic functions, maybe don't use zig.