
Rust Developer Drafts a Pre-RFC for Named and Optional Arguments
A post on botahamec.dev calls the absence of named and optional arguments Rust's most annoying gap, compares Dart, C# and TypeScript, and proposes an opt-in fix using the pub keyword.
A post on botahamec.dev argues that the most annoying gap in Rust is its lack of named and optional arguments. The author counts Rust, C#, TypeScript, Dart and Python among the languages he tolerates, and says Rust is the hardest of them to get named arguments out of. The piece ends with a pre-RFC of his own.
How other languages handle it
Dart, built for graphical interfaces where components carry many optional parameters, wraps named parameters in curly braces and allows default values, a `required` modifier and optional positional arguments in square brackets — the author calls it the best solution of the languages discussed. In C# any parameter may be named or given a default, as long as defaults follow the required ones, and named arguments can be passed out of order. TypeScript's optional positional parameters work well, but named parameters require destructuring a single anonymous object, so field names are written twice — verbosity the author dislikes.
What the gap costs Rust
Rust's usual workaround is a parameter struct implementing `Default`, with calls ending in `..Default::default()`. The post calls that worse than TypeScript's version: the types are not anonymous, defaults differing from the type's own require writing a whole function, and it works only when every parameter has a default.
For three optional parameters — capacity, hasher and allocator — the standard library's `HashMap` has eight factories, among them `new`, `with_capacity`, `with_hasher` and `with_capacity_and_hasher` with their `_in` variants, and the count grows exponentially. Order slips are easy too: in `fn print(text: &str, bold: bool, italics: bool, underline: bool)`, confusing the second and third argument quietly bolds the text instead of italicising it.
The proposal
The pre-RFC makes naming opt-in with `pub` before a parameter name — `fn print_labeled_measurement(pub value: i32, pub unit_label: char = 'm')` — so callers may write `print_labeled_measurement(value: 5)`. Named arguments must follow positional ones but may be reordered among themselves, and they may carry default values: const functions require constant expressions, while ordinary functions evaluate the default at instantiation. Traits may use named parameters and implementations must repeat the names, though trait methods cannot have defaults. Function pointers and the `Fn` traits stay positional.
Earlier proposals and open questions
The author also reviews proposals he considers worse: default struct field values (already on Nightly Rust, plus a polyfill crate called `feluments`), structural records, judged too hard to implement, a long Rust Internals Forum pre-RFC that proposed overloads rather than defaults, dot-prefixed arguments (a 2020 RFC that was not merged), and C#-style copying. Since names stay optional, safety becomes a matter of discipline; he suggests a Clippy lint or requiring names in a future edition. Left unresolved: argument order, the `pub` keyword, and whether defaults must always be const.
SiTech — AI-powered web development
We build fast, modern websites and bring AI into real business workflows. Have a project or a question? We'd love to help.