Add plain-simple way (in the standard library) for reading values from `stdin`?

I think I may have interpreted "challenges" differently than you meant -- I was thinking ACM ICPC, where there were definitely problems where people would use Java instead of C++ even when the preferred the later to be able to use java.math.BigInteger.

In that kind of an environment, I'd just start out by typing something like

    let mut s = String::new();
    std::io::Read::read_to_string(&mut std::io::stdin(), &mut s).unwrap();
    let mut input = s.split_whitespace();

which can just be copy-pasted into each of the problems.

Then when it comes time to read things, just do

    let x: i32 = input.next().unwrap().parse().unwrap();
    let y: i32 = input.next().unwrap().parse().unwrap();

which is certainly noisy, but also trivially-copy-pastable.

(It's not uncommon there to have someone just start typing out an algorithm you brought in your binder at the start of a contest; those three extra lines are negligible in comparison.)

In terms of simpler for that use case, I think I'd prefer a fn main() -> Yolo { that allows input.next()?.parse()? because it allows anything with ? and just panics on problems more than making the tokenizing much easier.

What belongs to std or doesn't have been discussed many times. Just because it is convenient to have some sort of read_input in std does not mean we should have it there. It's the same with RNGs, and the only reason I was mildly annoyed by that is because I was conditioned by other languages to expect RNGs in std. The proposed read_input function both writes to and reads from stdin, which is not reflected in the name, that's bad style. Finally, adding a line to Cargo.toml is the easiest solution ever. Any beginner can copy and paste a line.

3 Likes

Note that the only reason we have std::fs::read_to_string and std::fs::write is because it's convenient.

5 Likes

Okay, that was a bad argument, agreed. The rest I got right, hopefully :thinking:

1 Like

I slightly disagree with this in that I think access to at least the platform RNG could be appropriate in the std. Especially as the std already depends upon it. This is perhaps going off topic but the point I'd make is that what's in std or not seems (to me) to ultimately be somewhat arbitrary.

So there's always going to be good arguments for or against convenience features. And indeed what counts as being more than just convenience.

See this issue. Right now there is a PR to use getrandom inside std without exposing it in public API. After it lands we can move with a proper RFC for exposing getrandom in a similar fashion to alloc.

1 Like

One problem I have with baking toy APIs like this one into the standard library (which offer convenience, but are not necessarily defined precisely enough, or stable enough for non-interactive applications) is that people may be tempted to reach for them even in more serious use cases, like serialisation. My go-to example of how things may go wrong with this is a bug I reported in libsvgtiny, where sscanf was used to parse SVG path specifications, without regard for the fact that sscanf is locale-dependent, and that some locales' decimal formats may fail to agree with the format of decimal numbers inside an SVG path specification. sscanf is not exactly a toy API, but it's readily available, and yet so tricky to use in a controlled manner.

So I think this should be put in an external crate not to encourage overuse, as a form of syntactic salt.

2 Likes

Can you expand on how this is not defined precisely enough? This seems like a pretty thin layer over well-defined std::io APIs, and very clearly targeted at interactive APIs (and the documentation could make that extra clear).

In other words, I don't see how the risks you're talking about apply to this particular case, which seems very different from something like sscanf.

In this particular case, the risk of misuse seems quite small; but I think it's worth it to take a couple of steps back and look at the bigger picture. I remember a case where someone was using Display for serialising numbers into JSON, even though the only thing Display promises is that a human being should be able to read the string; not that the formatted number agree with the grammar of JSON. Also compare how when all you have is a regex, everything looks like a regular language.