So, I didn’t clearly explain my view in this thread, but maybe it will help to answer your questions:
(1) You don’t. If you have two functions to do different things, they should have different names. If they do the same thing, then one struct with optionals should be sufficient.
(2) Ditto - in my opinion, the same logic you use to say that’s a bad example applies to pretty much that entire class of situations, where passing an argument would turn a function into something completely different.
Keeping one name for one purpose improves both greppability and readability.
However, I agree that you don’t always have a sensible ‘default value’. To deal with this, as part of the conversion from function arguments to struct, you could use the presence or absence of an argument to determine Some or None. In fact, it might be simpler to require this for optional arguments rather than having any actual concept of a default value - the function body could just use unwrap_or if it wanted a default.
I don’t want to derail the RFC, since this is just my personal opinion, but since this thread is on discuss rather than a GitHub issue… here’s a basic strawman for what I’d like to see:
struct DrawTextArgs<'a> {
text: &'a str, // required
color: Option<Color>, // optional
font: Option<Font>, // optional
}
impl PaintContext {
fn draw_text(&self, args: ..DrawTextArgs) {
// use args.text, args.color, etc.
}
}
// Convenience methods taking the same arguments are common, which is why tying the arguments to a separate struct declaration makes sense.
impl Window {
fn draw_text(&self, args: ..DrawTextArgs) {
self.paint_ctx.draw_text(..args)
}
}
// usage
// Omitting keywords in calls to functions like the above, as well as using keywords on regular functions, should probably be possible, to avoid having two wildly different types of functions, although the latter would suddenly make argument names public API. Swift has a(n ugly) syntax to differentiate 'external' and 'local' parameter names...
// So these would all be valid.
win.draw_text(text, color);
win.draw_text(text: text, font: font);
win.draw_text(color: color, text: text);
Unresolved:
- What if you want a required argument of option type?
- Using anything but
: for keyword arguments would be hideous because it would be inconsistent with structs. Using : is apparently impossible due to type ascription. I suggest getting rid of type ascription.* ;p
*no, really. Having two operators (as, :) that both sort of mean “make A type T” (even if on a more detailed level they do totally different things) would be confusing as is, without the aforementioned conflict.