[Pre-RFC] named arguments

Hm, your approach may be indeed a better solution considering Rust's spirit. But note, that I propose to issue only warnings, not compilation errors, so you will not need #[allow_positional] for backwards compatibility. Of course it could be a compilation error instead, but I don't think it's worth the churn.

A huge :+1: for this proposal, although as mentioned already I would prefer if the arguments have to be named by default, and with an #[allow_unnamed_args].

1 Like

Why allow default arguments at all? Why wouldn't the reasoning to not implement default arguments not apply here?

The post describes the direction in which I would like for Rust to move and this includes default argument values (a.k.a optional arguments). Several people even think that named arguments don't have enough motivation on their own without default arguments (though I disagree with this opinion), for example:

In the real RFC I think default arguments should go to "possible future extensions" and probably proposed separately in its own RFC later.

Can you please re-iterate arguments against default arguments for informational purposes? I am sure default argument proposals were discussed extensively, but I haven't read those discussions and AFAIK those arguments haven't been raised in this thread.

2 Likes

I thought that it was an ABI thing for why rust didn't have default arguments, but I can't find a reference to it, nor can I find any lang team members who were actually against it in general, so I may have been mistaken. It looks like default arguments were just never implemented:

Optional arguments was cited as a major reason why the other major default argument proposal wasn't accepted (default optional arguments would solve the issues and do more, like what you are suggesting).

Relatedly, I wonder if instead of adding named arguments and default arguments as-is, it would be possible to extend structural records themselves with a Default impl that could allow code like

foo({ arg1: bar, ..Default::default() })

which would then solve both problems with structural records and save us of the problems "proper" named arguments usually cause.

6 Likes

My take on this using default field values + structural records is that we can have:

type Config = { height: u32 = 1080, width: u32 = 1920 };

fn open_window(config: Config) {
    // logic...
}

open_window({ height: 900, .. });

(..Default::default() would also work with just structural records)

14 Likes

My take on this using default field values + structural records is that we can have:

I like this direction a lot.

I still would like to see type inference for struct literals. I would love being able to replace the 'type Config' in your example with just a 'struct Config' and still being able to create a 'Config' from just '{ height: 900, .. }'.

I think currently type ascription makes this syntax ambiguous, but have this kind of type inference for structs would be IMHO a even more general solution.

Meh. I'd rather have a form of struct name elision, so you could still write

open_window({ height: 900, .. });

but Config would just be a regular struct:

struct Config { height: u32 = 1080, width: u32 = 1920 }
3 Likes

There's no technical reason why you cannot have both. :slight_smile:

6 Likes

I can't emphasize enough of how much I like this idea and approach.

2 Likes