Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upoptional parameters #152
Conversation
huonw
reviewed
Jul 3, 2014
| Since this is sugar for full overloading, a function declared with an optional parameter like this satisfies both | ||
| ```rust | ||
| pub trait ToStr { | ||
| fn to_str_(&self) -> String; |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
huonw
reviewed
Jul 3, 2014
| Inside the body of the function, the arguments will be pattern matched something like this: | ||
|
|
||
| ```rust | ||
| let rad = match args { |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
huonw
Jul 3, 2014
Member
Also, this implies that functionality that was previously "executed" at compile time (i.e. calling a different method to get different behaviour) would now, instead, be executed at runtime, as a switch over the number of arguments. Am I interpreting this correctly?
This comment has been minimized.
This comment has been minimized.
bstrie
Jul 3, 2014
Contributor
Is this something like Javascript's implicit arguments variable in each function?
This comment has been minimized.
This comment has been minimized.
huonw
reviewed
Jul 3, 2014
| Currently, you are able to write a function that differs by name to achieve the same effect. | ||
| This works for `slice_from` and `slice_to` and `slice`. | ||
| They are aptly named for what they do and can be easily autocompleted. | ||
| However, just one `slice` with two optional args (defaulting to 0 and the length of the string) |
This comment has been minimized.
This comment has been minimized.
huonw
Jul 3, 2014
Member
Could we have code examples for how the new slice function would be declared and called? (Having more examples would be good.)
This comment has been minimized.
This comment has been minimized.
huonw
Jul 3, 2014
Member
Sorry, I'll strengthen that: this needs more examples of declaration and of calling (e.g. I don't see any use of the ?(...) syntax other than the isolated mention in the text): this proposing a syntactic/ergonomic change so we need to be able to see what it looks like with clarity.
This comment has been minimized.
This comment has been minimized.
jnicklas
commented
Jul 3, 2014
|
I'd like to propose an alternate syntax. How about something akin to Java's overloading? fn concat(&self) -> String {
self.join(self, ",")
}
fn concat(&self, sep: &str) -> String {
...
}
// compile error, because the first parameter's type
// doesn't match the type of `concat` already declared.
fn concat(&mut self, sep: &str) -> String {
...
}
// compile error, because the second parameter's type
// doesn't match the type of `concat` already declared.
fn concat(&self, number: int) -> String {
...
}This feels like it has way more precedent, and it's quite clear how the syntax works, and we don't have to answer weird questions like what happens to |
This comment has been minimized.
This comment has been minimized.
s/ |
This comment has been minimized.
This comment has been minimized.
jnicklas
commented
Jul 3, 2014
|
@huonw yes, copy-paste error, I updated the comment. |
bstrie
reviewed
Jul 3, 2014
| } | ||
| ``` | ||
|
|
||
| traits. |
This comment has been minimized.
This comment has been minimized.
bstrie
Jul 3, 2014
Contributor
I don't understand what you mean by "satisfies both traits". Rust isn't duck-typed, and therefore you only satisfy a trait if you explicitly implement it. Merely implementing a function with a compatible type signature doesn't allow you to do anything generically.
bstrie
reviewed
Jul 3, 2014
| This will let Rust get rid of the sheer multitude of functions that only differ by a few parameters like | ||
| `concat` and `connect`; `split` and `splitn`. You can even go further and have a boolean indicating whether to | ||
| use terminator semantics and put that into `split`, eliminating `split_terminator`. | ||
| You could also have another boolean indicating whether it is reversed, eliminating `rsplitn`. |
This comment has been minimized.
This comment has been minimized.
bstrie
Jul 3, 2014
Contributor
Just a note here, but boolean flags are an API anti-pattern. I'd rather have separately-named functions.
bstrie
reviewed
Jul 3, 2014
| is much more elegant and doesn't clutter up the standard library with extra functions. | ||
|
|
||
| Of course, as I mentioned earlier, this also interacts with traits since now you satisfy two traits with one function. | ||
| This probably interacts with closures and/or lifetimes in some way as well. |
This comment has been minimized.
This comment has been minimized.
bstrie
Jul 3, 2014
Contributor
Yes, it would be impossible for any function to return a reference that in any way relied upon the lifetime of an optional input.
bstrie
reviewed
Jul 3, 2014
| However, just one `slice` with two optional args (defaulting to 0 and the length of the string) | ||
| is much more elegant and doesn't clutter up the standard library with extra functions. | ||
|
|
||
| Of course, as I mentioned earlier, this also interacts with traits since now you satisfy two traits with one function. |
This comment has been minimized.
This comment has been minimized.
bstrie
Jul 3, 2014
Contributor
Another reminder that this is not how traits work in Rust (see above).
bstrie
reviewed
Jul 3, 2014
| use terminator semantics and put that into `split`, eliminating `split_terminator`. | ||
| You could also have another boolean indicating whether it is reversed, eliminating `rsplitn`. | ||
|
|
||
| In this way, the library design is better, allowing auto-completion on `split`. |
This comment has been minimized.
This comment has been minimized.
bstrie
Jul 3, 2014
Contributor
In what way does the lack of optional parameters impede autocompletion?
This comment has been minimized.
This comment has been minimized.
iopq
Jul 3, 2014
Author
Contributor
I could want to "concat by character" and be looking for all functions that start with concat but it's actually connect.
bstrie
reviewed
Jul 3, 2014
|
|
||
| Currently in Rust there are a lot of functions that do the same thing, but take a different number of parameters. | ||
| The current design forces those functions to have different names. | ||
| This causes the standard library to have badly-named functions. |
This comment has been minimized.
This comment has been minimized.
bstrie
Jul 3, 2014
Contributor
I don't argue that some of our stdlib functions could be better named, but finding better names is not impossible. I also don't argue that optional parameters will allow strictly nicer names some of the time; god knows I've wished for them before. But keep in mind that up till now our stance has been that being forced to name your functions explicitly has been considered a feature, and that the lack of overloading/optional parameters has been an explicit choice (though entirely subjective). To overcome this inertia, you'd be best served by showing before/after comparisons of how real-life stdlib functions would look (both in definition and in usage) if this change were accepted.
This comment has been minimized.
This comment has been minimized.
iopq
Jul 3, 2014
Author
Contributor
I think I'd rather resubmit this as Java-style overloading. It's easier with static typing + no nulls. In C# you'd just go with unwrap(default = null) and call it a day. Not so easy in Rust since Option is more syntactically noisy.
This comment has been minimized.
This comment has been minimized.
|
@jnicklas, this is such an enormously wide-open design space that I don't want to sidetrack the comments here discussing alternatives. Note as well that this particular RFC explicitly rejects Java-style overloading. Given that people have certainly asked for overloading in the past (especially among C++ developers, our key demographic), I would suggest that you propose an entirely separate RFC if you'd like to discuss it. But if you do so, please make sure it's complete and well-considered; submit a pre-RFC to the mailing list if you'd like to solicit opinions and feedback. |
This comment has been minimized.
This comment has been minimized.
|
Note that there is a great deal of discussion at rust-lang/rust#6973. I would encourage this RFC to plan for a backwards-compatible design as it may otherwise be difficult to fit this in before 1.0 is released. |
This comment has been minimized.
This comment has been minimized.
arcto
commented
Jul 3, 2014
|
@alexcrichton, I believe the reason this should be discussed before 1.0 is that, with overloading, some functions in the standard library could possibly be given better/more consistent names. |
This comment has been minimized.
This comment has been minimized.
arcto
commented
Jul 3, 2014
|
I agree with @jnicklas in that explicitness makes overloading clearer and simpler - syntactically and semantically, imho. If two functions share parts of the implementation one can always call one function from the other and have the compiler inline the call.
|
steveklabnik
reviewed
Jul 3, 2014
| } | ||
| // compile error, because the first parameter's type | ||
| // doesn't match the type of `concat` already declared. |
This comment has been minimized.
This comment has been minimized.
steveklabnik
Jul 3, 2014
Member
We don't currently have any kind of ordering for declarations, right? This introduces some kind of ordering.
This comment has been minimized.
This comment has been minimized.
|
@arcto, at least in theory, Rust's libraries and tooling have powerful enough support for versioning that it will be possible to evolve the stdlib independent of the language (though each version of the stdlib will obviously require some minimum Rust version), and you'll trivially be able to make use of multiple versions of the stdlib in the same project if you really want. I agree that it's crucial to have a good stdlib API for 1.0, but this is just pointing out that our definition of "good API" is allowed to change at our leisure over time, as Rust gains features. |
This comment has been minimized.
This comment has been minimized.
|
Thanks for submitting the RFC. Whilst optional parameters may be something we add to Rust in the future, it is something that has been discussed before and there is broad agreement that it wouldn't be added before 1.0. Therefore, this RFC is extremely likely to be closed as postponed. |
This comment has been minimized.
This comment has been minimized.
Can't it just be left open with a milestone? |
This comment has been minimized.
This comment has been minimized.
|
We do give them with a "milestone" (i.e. tagged with |
This comment has been minimized.
This comment has been minimized.
|
Closing. While optional arguments are an oft-requested feature, it has long been our position that it is non-essential and can be reconsidered backwards-compatibly at some point in the future. Thank you. |
brson
closed this
Jul 10, 2014
This comment has been minimized.
This comment has been minimized.
|
This probably should have gotten the |
This comment has been minimized.
This comment has been minimized.
|
Filing with RFC issue #323 |
iopq commentedJul 3, 2014
RFC for optional parameters added to Rust functions