Python has really convenient functions for interacting with the user over the command line. The print()
function for printing to stdout with a newline by default, and the input()
function to get a line from stdin with an optional prompt to the user.
While Rust has convenient equivalents to Python’s print()
function, print!
and println!
, there is no such equivalent to input()
. I think there should be. It would make interacting with the user so much easier, which is important for demonstrating the power and ease of use of a language to beginners.
Currently, getting a line from stdin is quite clunky, and does not include the ability to prompt the user:
fn main() {
print!("Input your age: ");
let input = std::io::stdio::stdin().read_line().unwrap();
}
Getting multiple inputs is even clunkier, because the recommended practice is retaining the buffered handle so there’s no extra allocation:
fn main() {
let mut stdin = std::io::stdio::stdin();
print!("Input your name: ");
let name = stdin.read_line().unwrap();
print!("Input your age: ");
let age = stdin.read_line.unwrap();
}
This requires knowledge of how Writers work, knowledge of mutability, awareness of how modules work and of std::io::stdio::stdin()
. This delays the use of user input in beginner examples until all of the above is covered, or else we run the risk of confusing and discouraging the fledgling Rustacean. It’s also very noisy in general.
An input
macro would make this so much simpler:
fn main() {
let name = input!("Input your name: ");
let age = input!("Input your age: ");
}
The last block of code is the most clear and concise, and can be taught right alongside usage of print!
and println!
, making beginning code examples much more interactive. It should take formatting arguments for printing the prompt just like its output counterparts. Called with no arguments, it should print nothing and wait for a line.
This macro can fail internally on unwrap
, but print!
and println!
also fail internally if there was an error printing to stdout, so it’s not really a new issue.
This shouldn’t be a breaking change, except for code that uses a third-party input!
macro, which would likely be redundant with this change anyways.
##Pros
- Improve interactiveness in beginner examples
- Reduce noise and boilerplate in code that interacts bidirectionally (input and output) with the user
##Cons
- Another macro to implement, maintain, and teach
- Still requires type conversion for any input other than String.
- Type conversion should be taught early anyways.
##Alternatives
- Do nothing
- All existing problems with the current approach remain, but no additional effort required.
- A non-allocating
input_line()
function exported in prelude that returns String.- Still requires separate prompting