I also like the .arg
suggestion.
I re-read the RFC by mentally replacing 'arg
by .arg
and I think that the result is great.
With the introduction of const generics you'll be able to pass chars as const arguments, I don't know how often you would see char
const parameters though (so this might be a moot point).
#![feature(const_generics)]
pub fn foo<const BAR: char>(){}
fn main(){
foo::<'a'>();
}
I think I'll also replace the =
with :
to be more similar to struct syntax:
free_fall(.z0: 100.0, .v0: 0.0, .g: 9.81);
.
+ :
that's a lot of dots
I think I prefer =
. It's also safer in case type ascription ever gets stabilized.
Since we are all bikeshedding syntax here, how about...
foo(a := 3)
Yes, it's a brand new composed sigil - but it's something people expect to have something to do with binding.
Another option is:
foo(a => 3)
If we borrowed block syntax from Ruby, why not that?
Which is probably not possible to add to Rust (at least not for a long time) because it breaks macro_rules!
matchers.
Why? Because they'll parse them as two sigils? How about keeping them two sigils but formatting them without a space between them?
"What should be the syntax" is probably the least important problem with named arguments. This is yet another RFC that proposes a new syntax but completely fails to address the many questions that had been raised before. More syntax is not what we need for a good named arguments proposal, fleshing out details of semantics is.
Is there a sum-up of those concerns somewhere?
@H2CO3 in an unrelated note, I want to thank you for keeping track of the general direction of Rust, and say "no" when needed. Rust is such a good language, in part due to all the "no" that have been said in the past. I personally would love any kind of named arguments, but they should not have drawbacks to current and future extensions.
This post was my attempt at a 10,000 foot view summary, and given the number of <3s on it I assume people feel it's at least vaguely accurate. But it's probably more concise than what you're after. I think the rest of that thread did a decent job fleshing out some parts of it, but certainly not all, and this new thread is kinda not touching on any of it except syntax (I hadn't posted in this thread before because there's only so many times I can say "this is all academic bikeshedding; you're missing the real problems" before it starts sounding rude even to myself).
But we're definitely missing a proper summary of these issues, like I did for orphan rules issues a while back. It'd take someone more interested in named arguments than me to make one.
I would like to discuss the more important concerns more, but so far almost no concerns besides the syntax were raised.
@lxrec I read your summary, and I believe that my RFC addresses most of the points you raised. I will further extend the Motivation section later today, to discuss why I believe enums and newtypes aren't sufficent.
I had the same conclusion. I started to write down the points that were raised in @Ixrec, but I think that they were addressed (especially since both 'arg
and .arg
don't conflict with any existing or planned features like types ascription). I also think that the motivation section clearly explain why named arguments would be a good addition to the language.
However, it should be clarified in the alternative section that the addition of structural record isn't incompatible nor sufficient to cover what this RFC brings.
The likes on keyword/optional args wishlist is an indication of how much perceived need/interest there is on a feature like this.
Apart from this post, there are a couple of excellent comments on that thread listing motivations:
- https://github.com/rust-lang/rfcs/issues/323#issuecomment-426918479
- https://github.com/rust-lang/rfcs/issues/323#issuecomment-508943863
Structural records (which btw, is not an accepted RFC yet) is frequently mentioned as a alternative to this. But as I have argued before, it is a poor substitute for function arguments.
I don't think that supporting both named and positional arguments for the same argument (ie, beeing able to use both foo(value)
and foo(.arg = value)
as we prefer) should be added in this first MVP, if at all. However, in case we want to be able to support such extensions later, I think we should forbid leading underscore in argument identifiers (ie ._named
).
Likes do nothing to indicate how many people are against a feature. They're not a voting mechanism. (And if you start to measure it like one, it will be gamed like one.)
Here’s a weird idea: what if calling functions with curly braces instead of parens had the same rules as initializing a structure? This would allow for both named arguments and positional arguments in an ABI compatible manner. I don’t think this would be backwards compatible because structs and functions are in the same namespace, however it would be a very small break as structs are usually capitalized and functions are lower case.
Do you mean something like
fn do_something { arg1: i32, arg2: i32 } -> i32 {
arg1 + arg2
}
do_something { arg1: 18, arg2: 24 }
I believe that would be possible. The only downsides are that you can't mix positional and named arguments, and that it looks a lot like a struct.
Not quite what I mean; you wouldn't have to use curly braces in the declaration, only the call. You would get to choose whether or not you call a function via position or name. So the following:
fn do_something( arg1: i32, arg2: i32 ) -> i32 {
arg1 + arg2
}
// Both are valid:
do_something { arg1: 18, arg2: 24 }
do_something(18, 24)
I think you could make that backward compatible with an annotation:
#[allow_named_arg_call_or_whatevs]
fn do_something( arg1: i32, arg2: i32 ) -> i32 {
arg1 + arg2
}
Which would make it fail to compile if the struct do_something
is already defined. Essentially, you just treat it as a fn
and struct
definition at the same time.
Or perhaps even more boldly:
struct fn do_something( arg1: i32, arg2: i32 ) -> i32 {
arg1 + arg2
}