Yes, that could've been lended almost as-is from OCaml, in particular as Rust doesn't have partial application so optional arguments would work out-of-the-box as well.
https://github.com/rust-lang/rfcs/issues/323 is the oldest currently open tracking issue, as you can see it has 397 comments. And that thread you linked has 171. Basically, tons of people that feel basically every possible way.
I also feel at this point it's basically a wontfix, but that's more because it's both controversial and huge, and arguably not as high of a priority as other things even if it weren't those two things. The reason it gets huge is that you really want to consider all three of {optional, named, variadric} at roughly the same time.
I do think that people are generally more supportive of variadric than optional/named.
I'm guessing that general support doesn't translate to support for a specific syntax with changes to the calling convention. I wouldn't put money on this coming together any time soon.
It doesn't think about optional arguments (but somehow does include overloading). And a bit in a related fashion, it doesn't permit for reordering calling arguments, which I consider a downside:
> Reordering named arguments when calling
> No it is not possible. Just like unnamed arguments and generics, named arguments are also position-based and cannot be reordered when calling: register(name:surname:) cannot be called as register(surname:name:).
> Reordering them at the definition site is an API break, just like reordering unnamed arguments or generics is an API break already.
The rationale for this expressed in the comments says it's incompatible with overloading, but to me I don't see why named arguments and overloading should go hand-in-hand—or, indeed, how desirable overloading is in the first place. Or why should overloading be able to overload that kind of scenario. The other reasons for this don't seem really problems at all.
> func2 and func3 could work in theory: named arguments as proposed in this RFC are position-based and their internal names are different: just like two arguments can have the same type without ambiguity, those functions could be allowed.
Maybe there are technical reasons that are simpler when considering type compatibility between function types that have or don't have labeled arguments? Seems the proposal has misunderstood something about OCaml labeled arguments when placing it under https://internals.rust-lang.org/t/pre-rfc-named-arguments/16... , though.
In addition the proposal doesn't seem to have a neat syntax for forwarding named parameters, like in constructing records you can just fill in a field called foo by mentioning its name by itself—or, like in OCaml you can have
let foo ~bar = bar + 1
let baz ~bar = foo ~bar
let main () = baz ~bar:42
If it used the .-prefix as mentioned as an idea elsewhere, then this too could be naturally expressed.
Maybe there are other ideas how to go about the labeled arguments, though that one seems pretty well thought-out.
One thing I've enjoyed with Python (and Mypy) is the ability to require the caller to use named arguments with the asterisk marker in the parameter list. This idea is mentioned in the proposal.
I'm all for named parameters. C++ is sorely lacking that feature as well.
Currently using vs code with C++, I like how it handles the missing language feature by adding a grayed out parameter name before the value for function calls and initializers. Maybe there is something like that for rust.
could you do that with `struct` / `record` fields? In JavaScript which doesn't have named function parameters either I often write functions with a single `cfg` parameter that are called like `f({ hours: 2, seconds: 53, })` which I find nice b/c it re-uses existing data structures.
In Rust, you can't implicitly omit fields when instantiating a struct, so it would have to be a bit more verbose, explicitly using Rust's analog to the spread syntax.
Adding support for struct default field values would allow for
- leaving some mandatory fields
- reduce the need for the builder pattern
- enable the above to be written as f(S { hours: 2, seconds: 53, .. })
If that feature ever lands, coupled with structural/anonymous structs or struct literal inference, you're getting everything you'd want from named arguments without any of the foot guns.
Has anyone ever proposed it? It's such a straightforward feature with such obvious semantics ("default field values are const contexts") and impossible-to-bikeshed syntax (`a: i32 = 42`) that I've been meaning to write up an RFC myself for around, oh, ten years now...
Last time I had this conversation[1] the main sticking point were around semantics of private fields, but I am convinced that the maximally restrictive version can be done (only pub fields can be optional) and maybe relaxed later after we get some real world experience. The other thing was about whether the default values needed to be const, but that makes sense as a restriction to me.
Yeah makes sense! I haven’t felt the need for this feature personally, but it feels like it fits with the language pretty well to me. The big issue with default values (as far as I’m concerned) is for them to always have a default value, and this doesn’t change the opt-in nature of the concept.
The issue I have with Default is that the verbosity jump from derive(Default) to impl Default for Type is high, evej if you just want to specify a single field. The other reason I want this is because it makes defining builders almost trivial for any case where custom logic isn't needed for the fields. I would expect the impl-based builder pattern to become more niche if we had this feature. Your reason is yet another that would be nice to address as well. I like how this one change addresses multiple things at once.
Yeah, full agreement here. I almost said something along the lines of "it's almost like extending #[derive(Default)] with serde-like attributes to control which fields get what defaults, but with nicer syntax," but got a little lazy with it since we're in agreement anyway. It is annoying that deriving Default is all or nothing.
I didn't even think about the builder thing, but you're right there too.
Well the beautiful thing about software engineering is that pretty much everything is possible, it essentially boils down to "but should you really"? :-)