4 ms·
You want to see sadness, from a learning curve point of view? How to read from stdin on Rust. https://stackoverflow.com/questions/30186037/how-can-i-read-a-si
by yodelshady 6y ago
You want to see sadness, from a learning curve point of view?
How to read from stdin on Rust.
https://stackoverflow.com/questions/30186037/how-can-i-read-a-single-line-from-stdin https://stackoverflow.com/questions/30186037/how-can-i-read-...
Naturally, `read_line` returns the number of bytes read, rather than... the line. If you want a function or macro that does simply return a string, the best way is to... download an external crate? Because nothing says "security" more than third-party dependencies for basic tasks.
Incidentally, use of said crates is different dependent on Rust 2015/2018. Half of the internet resources you will see are wrong. If you already understand the differences, you'll know which is which.
Oh, and if you see "type" unaware in a Rust codebase, you know the one thing it isn't... is a type. Generics are sometimes elided, sometimes not, and sometimes live in a separate namespace.
Oh, and if you test code on a static array of length < 32, and a similar array of length > 32, you will see completely different behaviour.
Oh, and no REPL. This has got to be my single favourite thing about Python - I am literally never surprised. Because any, single, line of code I'm not 100% on is tested in seconds. A browser-based substitute is just that, a very poor substitute.
Rust has good points, but some huge ergonomic difficulties for a beginner, that are nothing to do with "the core difficulty of programming" - you'll note I've not even mentioned how a reader is supposed to comprehend what a <&'a T> is. The best I can say is that it's good gatekeeping.
- zozbot234 6y ago> Naturally, `read_line` returns the number of bytes read, rather than... the line. That decouples the concern of allocating the buffer from reading the actual line. It should be possible to write a wrapper that does "return the line" (in an owned buffer), and that might be a bit cleaner in simple cases. But the stdlib should focus on providing essential functionality first. > Oh, and if you test code on a static array of length < 32, and a similar array of length > 32, you will see completely different behaviour. This will most likely change after const generics get fully stabilized. The current code is already using them under the hood, but the separate behavior for size>32 is being kept for forward compatibility in case const generics need to change. > you'll note I've not even mentioned how a reader is supposed to comprehend what a <&'a T> is. That comes up almost exclusively when working with references that have different lifetimes. Rust tries to deduce lifetimes whenever possible so that writing them out isn't necessary most of the time, but sometimes the programmer has to resolve ambiguity. The whole system is still quite intuitive.
- yodelshady 6y ago>It should be possible to write a wrapper that does "return the line" (in an owned buffer), and that might be a bit cleaner in simple cases. So put it in std lib. The point of computers is to not force humans to duplicate identical, basic tasks millions of times, and a major selling point of Rust is zero cost abstractions. Stdlib Rust has everything necessary to write a read_line that returns a good abstraction - Result<&str, Err> - and instead provides a leaky one. I shouldn't be giving a pigs' ear about the buffer length. And come on, a language with vec.windows() in the std library is not minimal. It's just inconsistent.
- Misdicorl 6y agoWell actually you couldn't return an &str, because it would be dropped at the end of the read. You'd need to return either a String (and that would be a big mistake) or a Vec of u8. Which I'm sure you'd also be unhappy with
- yodelshady 6y ago>It should be possible to write a wrapper that does "return the line" Is it, or not? What's the point of lifetimes if you can't manage that trivial outlives-the-creator task in literally every other language ever with them? Why would a String be a big mistake? You STILL think Rust is easy to learn?
- estebank 6y agoIt is. The reason it is not in the stdlib is because it is a foot-gun. Quoting myself from elsewhere in this thread[1]: > Other languages aimed at ease of use will just allocate for you and give you the fully baked contents in a single fn call, but when you're writing code that 1) has to be called often enough where allocations can show up in your flame graphs or 2) the input is big enough that you can't realistically keep the entire thing in memory at once, you suddenly have to care about what the fn is doing internally. Making the default API for file interaction require you pass in your own buffer makes this explicit at the cost of some ease of use. [1]: https://news.ycombinator.com/item?id=23811980 https://news.ycombinator.com/item?id=23811980
- jki275 6y agoread_line returning the number of bytes read instead of the bytes is a C thing. That's just how you do things in C. Not arguing it's the best way -- and I far prefer the C++ way of returning a string or a buffer -- but it's the C way.
- twic 6y agoIt's how Java's InputStream and Reader work, too. In any language, requiring the caller to supply the buffer is a prerequisite for efficiency.
- estebank 6y agoAs the sibling comment said it's not a C thing. It is done that way in C because you have to babysit allocations. Other languages aimed at ease of use will just allocate for you and give you the fully baked contents in a single fn call, but when you're writing code that 1) has to be called often enough where allocations can show up in your flame graphs or 2) the input is big enough that you can't realistically keep the entire thing in memory at once, you suddenly have to care about what the fn is doing internally. Making the default API for file interaction require you pass in your own buffer makes this explicit at the cost of some ease of use. Seeing this will also serve as a teachable moment, when the dev looks at the docs trying to understand why it has such an obtuse API, hopefully coming away with this comment's explanation. This might seem to be a pedantic distinction but I've seen Java codebases where buffer reuse was mandatory in the hot path and Rust is all about removing foot guns.
- jki275 6y agoI agree with you on why it’s done that way in C, and certainly it can be in other languages. No argument there. But it really is a C thing, because that’s just “how you do it” in C.
- deleted 6y ago[deleted]