The approach which makes the most sense (to me) is just to have each default be a const
item. The default is const evaluated, and then calling the function without a default argument is just sugar for foo(arg, DEFAULT_ARG)
. There's no question about what the semantics of such a feature would be.
The actual blocker is more on other interesting questions/limitations:
- Can you use
fn foo(u32, u32=0)
asfn(u32)
? Asimpl Fn(u32)
? - Can you default non-tail arguments? How much of std is going to feel second-class because its arguments were put in the wrong order for defaulting?
- Everywhere else fields are elided, we use
..
to indicate that things are missing, why is function defaults different? - How do argument defaults interact with traits?
- What about defaulting arguments of generic type?
There's a number of unanswered questions, along with whether we actually want default arguments, or if we'd be better served by supporting the arguments struct pattern more directly. Default arguments have a tendency to lead to functions with a ton of defaulted arguments, and putting them in a struct makes for cleaner expansion and named (field) arguments.
In a future Rust, I envision something like
// pretend this is an impl
fn Database::new(struct {
port: Ip,
file: File,
trace_span = None::<Span>,
config = Config::default(),
..
});
If we had something like this, there's much less need for default arguments.