rfcs icon indicating copy to clipboard operation
rfcs copied to clipboard

Wishlist: functions with keyword args, optional args, and/or variable-arity argument (varargs) lists

Open pnkfelix opened this issue 9 years ago • 397 comments

A portion of the community (and of the core team) sees one or more of the following features as important for programmer ergonomics:

  • keyword-based parameters (as opposed to position-based parameters),
  • optional parameters (where one provides a default value for them, usually in the parameter list),
  • variable-arity functions (which can be seen as a generalization or variation on optional parameters, depending on how you look at it).

This issue is recording that we want to investigate designs for this, but not immediately. The main backwards compatibility concern is about premature commitment to library API's that would be simplified if one adds one or more of the above features. Nonetheless, We believe we can produce a reasonable 1.0 version of Rust without support for this.

(This issue is also going to collect links to all of the useful RFC PR's and/or Rust issues that contain community discussion of these features.)

pnkfelix avatar Sep 25 '14 22:09 pnkfelix

Nonetheless, We believe we produce a reasonable 1.0 version of Rust without support for this.

depends on how you see it. the API will definitely be well-considered given the constraints of no default/kw arguments.

but once those are added, i’m sure the API will be considered lacking, especially in areas where new defaults render old functions obsolete.

a good example (if the new syntax sugar wouldn’t exist) would be ImmutableSlice:

fn slice(&self, start: uint, end: uint) -> &'a [T];
fn slice_from(&self, start: uint) -> &'a [T];
fn slice_to(&self, end: uint) -> &'a [T];

slice_from and slice_to will be immediately obsolete once you can just leave out start or end from slice. i bet there are hundreds of examples more.

flying-sheep avatar Oct 08 '14 16:10 flying-sheep

@flying-sheep so then you deprecate such methods, just like today, no?

pnkfelix avatar Oct 09 '14 07:10 pnkfelix

@pnkfelix I think his argument is that we don't want to be stuck with a ton of deprecated cruft in the stdlib, but I'm still personally not too sympathetic to the need to have default arguments before 1.0.

reem avatar Oct 09 '14 09:10 reem

yeah, that’s my argument. either cruft, or lengthy deprecation formalities and rust 2.0 a year after 1.0 (semver requires a major version bump for breaking changes)

flying-sheep avatar Oct 09 '14 19:10 flying-sheep

While I'd prefer to have optional/keyword args before 1.0, I believe the problem with deprecated functions crufting up the API can be substantially lessened by removing such functions from the generated API docs. This is how the Qt project (and D AFAIK) handles API deprecation; the deprecated stuff continues working but developers writing new code don't see it.

Of course, the generated docs should have a setting/link/button to show the deprecated API items but it should be off by default.

I think this is also a good idea in general; just a couple of days ago I accidentally used a deprecated function because it seemed like a good pick and I didn't notice the stability color.

Valloric avatar Oct 10 '14 20:10 Valloric

Rustdoc's handling of deprecated items definitely needs some improvement - see rust-lang/rust#15468 for some discussion.

sfackler avatar Oct 10 '14 20:10 sfackler

See the "Struct sugar" RFC for another take.

aturon avatar Feb 03 '15 23:02 aturon

I'd like to see some of these RFCs revived in the near future, if someone has time to do so.

gsingh93 avatar May 18 '15 21:05 gsingh93

Agreed, there's a whole bunch of different keyword arguments proposals floating around and there's been a few discussions which seemed to die off a few months ago... would love to hear the current standpoint on this.

aldanor avatar May 23 '15 23:05 aldanor

Ok, 1.0 released, even more, can we please discuss it again? especially default arguments.

e-oz avatar Dec 04 '15 19:12 e-oz

This issue is open, it's free to discuss.

steveklabnik avatar Dec 04 '15 20:12 steveklabnik

This issue is open, it's free to discuss.

(though its possible an https://internals.rust-lang.org post might be a better UI for undirected discussion ... we didn't have the discuss forums when we set up these postponed issues...)

pnkfelix avatar Dec 04 '15 21:12 pnkfelix

I'd love to see keyword arguments. I opened a thread on /r/rust with some comments about them before finding this issue. I guess /r/rust is an appropriate place for "undirected discussion" too?

yberreby avatar Dec 10 '15 09:12 yberreby

In any case, this should be done in such a manner that it does not cause very inconsistent libraries, perhaps by letting the named parameters be optional? For example the names could be given by the argument name. Such that, the function:

fn func(a: u8, b: u8) -> u8;

can be called both with and without named parameters, for example:

func(a: 2, b: 3)

or something along this, while still being able to do:

func(2, 3)

ticki avatar Dec 10 '15 12:12 ticki

Also, this feature could easily be misused by taking named parameters instead of structs, which, I think, is a bad thing.

ticki avatar Dec 10 '15 12:12 ticki

I think it's because supposedly people are thinking about some kind of heterogenous variadicity (like the case of println, which is currently done with macros), and that isn't possible with arrays.

golddranks avatar Dec 10 '15 12:12 golddranks

I see, but that's why we got macros. If you want heterogenous variadicity, you gotta go with macros, after all the Rust macro system is very powerful.

ticki avatar Dec 10 '15 13:12 ticki

I agree, macros are appropriate for this.

yberreby avatar Dec 10 '15 13:12 yberreby

When I was first learning Rust pre-1.0, hearing that keyword arguments were not going to be implemented for 1.0 seemed like a terrible choice. From a background in Ruby/Python/JavaScript, keyword arguments are a very common and natural way to create nice APIs.

However, after actually using Rust for a while, I've actually grown to like the struct/builder pattern much more than keyword arguments. The problem with making keyword arguments easy is that it encourages functions that do too much by taking a bunch of different options.

If, instead, you are restricted to positional arguments, then you're more inclined to keep functions small, with a smaller surface area for their signatures. If there a small number of variations on the behavior of a function, these can exist as different named functions (e.g. alternate constructors.) If there really are a large number of variables needed for a function, pulling those variables out into a dedicated struct provides basically all the benefits of keyword arguments, plus the possibility of reuse.

I think if keyword arguments are added, they should just be syntactic sugar for functions that take a struct argument.

jimmycuadra avatar Dec 10 '15 13:12 jimmycuadra

If you want heterogenous variadicity, you gotta go with macros, after all the Rust macro system is very powerful.

And then you have to limit the length of your heterogeneous lists to ~10 to avoid horrible metadata bloat. Macros help, but it's still a half-measure.

petrochenkov avatar Dec 10 '15 13:12 petrochenkov

@jimmycuadra I agree. Functions should be small and compact, however sometimes you want to be able to know the argument order without looking up the signature (which keyword arguments solve), even though structs and other type constructions should always be prefered over named parameters, when dealing with larger amount of inputs.

One thing that's important to me is consistency with the current call syntax (such that it's up to the caller whether to use named arguments or not). This can be achieved in the way I described in my previous comment.

ticki avatar Dec 10 '15 13:12 ticki

@petrochenkov The problem you outline is a problem with macros, not a need for method variadicity.

ticki avatar Dec 10 '15 13:12 ticki

Also, this feature could easily be misused by taking named parameters instead of structs, which, I think, is a bad thing.

No, using structs instead of named arguments is a bad thing. And using array instead of arguments is a horrible thing.

I agree, macros are appropriate for this.

For named arguments? Or for optional arguments? Writing macros for EACH function, export/import it - it's very over-verbose.

I think if keyword arguments are added, they should just be syntactic sugar for functions that take a struct argument.

No way. Better not implement it at all than this.

Functions should be small and compact

Let each user decide how their functions should look. Don't roll into Go-ideology "we don't have it because you don't need it and we know better".

e-oz avatar Dec 10 '15 14:12 e-oz

Really frustrated to see such comments. All modern languages except Go have it, but Rust "don't need it, because macros". What a shame.

e-oz avatar Dec 10 '15 14:12 e-oz

No, using structs instead of named arguments is a bad thing.

Not true. Structs are strongly typed (hence less prone to errors) and makes it possible to efficiently reuse codes. Your functions shouldn't take a large number of arguments anyway.

And using array instead of arguments is a horrible thing.

This is not true. Using arguments instead of arrays is a horrible thing.

For named arguments? Or for optional arguments? Writing macros for EACH function, export/import it - it's very over-verbose.

It not very often you run into lack of variadic functions, and when you do, you can write a macro, and when generic integers lands, you can just use arrays. Often functions takes a fixed number of arguments anyways.

Also, note that the macro syntax will soon be revised.

Let each user decide how their functions should look. Don't roll into Go-ideology "we don't have it because you don't need it and we know better".

One of Rust's design philosophies is that Rust should not lead the user into bad code, bugs, and logic errors (this is the reason why we don't have increments, for example). We're all lazy after all, but there is no reason to encourage being lazy.

ticki avatar Dec 10 '15 14:12 ticki

Your functions shouldn't take a large number of arguments anyway.

I will decide it, not you.

Structs are strongly typed

function arguments too.

Often functions takes a fixed number of arguments anyways.

If your functions often take fixed number of arguments, all other users should obey?

One of Rust's design philosophies is that Rust should not lead the user into bad code

And again - what is bad code will decide user, not some very arrogant community members.

e-oz avatar Dec 10 '15 15:12 e-oz

If your functions often take fixed number of arguments, all other users should obey?

I'm just saying that introducing syntactic sugar for such a small special case is not worth it. This job is better suited for macros.

And again - what is bad code will decide user, not some very arrogant community members.

Sure, user should not be forced to not writing bad code, but neither should they be encouraged to.

ticki avatar Dec 10 '15 15:12 ticki

Just a friendly reminder everyone: let's try to keep conversation civil and constructive! Thanks.

BurntSushi avatar Dec 10 '15 15:12 BurntSushi

Are keyword-based arguments must be mandatory for all or it is up to me?

KalitaAlexey avatar Dec 10 '15 15:12 KalitaAlexey

@KalitaAlexey I'm not exactly sure what you're asking, but I supose you mean "Is it mandatory to provide the name of the parameters to the function, if we get keyword arguments". And the answer is no, because that would break backwards compatibility.

ticki avatar Dec 10 '15 15:12 ticki