- Start Date: 2014-09-30
- RFC PR: (leave this empty)
- Rust Issue: (leave this empty)
Features:
- A sugar for structs with optional arguments
- A sugar for declaring all members of a struct public
- Language change: Function call syntax for named arguments
Goals:
- Refactor friendly syntax
- Error safe function call syntax
- Improve readability and ergonomics
Remove redundant typing when ...
- ... returning a struct from a function or expression block
- ... initializing collections, for example a vector
- ... handling optional function arguments
- ... destructuring a struct with optional values
Improve ergnomics for structs, add named argument syntax and optional arguments.
The idea can be illustrated with a toy example:
// `pub:` makes all members public.
pub: struct Character<'a> {
first_name: &'a str,
last_name: &'a str,
age: u16,
father: Option<&'a str>,
mother: Option<&'a str>,
children: Option<&'a [&'a str]>,
home_town: Option<&'a str>,
favourite_food: Option<&'a str>,
partner: Option<&'a str>,
abilities: Option<&'a [&'a str]>
}
impl World {
// World has different representation of a character,
// therefore the arguments are pointers and not values.
fn add_character(&mut self, Character {
first_name,
last_name,
age,
father,
mother,
children = [].as_slice(),
home_town,
favourite_food = "pizza",
partner,
abilities = [].as_slice()
}) {
...
}
}
let last_name = "Brown";
world.add_character(
first_name: "Mike", last_name, age: 56, children: vec!["Julia"].as_slice(), ..
);
world.add_character(
first_name: "Julia", last_name, age: 15, father: "Mike", ..
);
This gets desugared into:
pub struct Character<'a> {
pub first_name: &'a str,
pub last_name: &'a str,
pub age: u16,
pub father: Option<&'a str>,
pub mother: Option<&'a str>,
pub children: Option<&'a [&'a str]>,
pub home_town: Option<&'a str>,
pub favourite_food: Option<&'a str>,
pub partner: Option<&'a str>,
pub abilities: Option<&'a [&'a str]>
}
pub struct World;
impl World {
// World has different representation of a character,
// therefore the arguments are pointers and not values.
fn add_character(&mut self, Character {
first_name,
last_name,
age,
father,
mother,
children,
home_town,
favourite_food,
partner,
abilities
}: Character) {
let children = match children.to_option() {
None => { [].as_slice() },
Some(val) => val
};
let favourite_food = match favourite_food.to_option() {
None => "pizza",
Some(val) => val
};
let abilities = match abilities.to_option() {
None => { [].as_slice() },
Some(val) => val
};
...
}
}
let last_name = "Brown";
world.add_character(Character {
first_name: "Mike",
last_name: "Brown",
age: 56,
father: Optional::none(),
mother: Optional::none(),
children: Optional::some(vec!["Julia"].as_slice())),
home_town: Optional::none(),
favourite_food: Optional::none(),
partner: Optional::none(),
abilities: Optional::none()
});
world.add_character(Character {
first_name: "Julia",
last_name: "Brown",
age: 15,
father: Optional::some("Mike"),
mother: Optional::none(),
children: Optional::none(),
home_town: Optional::none(),
favourite_food: Optional::none(),
partner: Optional::none(),
abilities: Optional::none()
});
In the example above, the sugar requires 53% of the characters, even there are only two characters involved. With a similar named syntax for functions, the sugar requires 42% of the characters.
What's the state of this RFC? I can't find any issue or PR for it.