3 ms·
I'm not glossing over it, I said that this is better written using results. Complaining about the existence of Parse is like complaining about the existence of
by detrino 11y ago
I'm not glossing over it, I said that this is better written using results.
Complaining about the existence of Parse is like complaining about the existence of unwrap in Rust.
C++ (another systems language) is probably a better comparison for out of memory.
- kibwen 11y agoMoving my ninja edit down here into a reply: On modern systems it's not possible for an application to know when memory has been exhausted, because of virtual memory and overcommit (http://www.win.tue.nl/~aeb/linux/lk/lk-9.html#ss9.6 http://www.win.tue.nl/~aeb/linux/lk/lk-9.html#ss9.6). The system will happily tell your process that memory is available even when it's not, and relies on the OOM killer to free memory by force when necessary. The only context in which an application can reliably detect OOM is when that application is the kernel itself. Fortunately, Rust has a stripped-down version of the standard library, called libcore, that exposes features which don't require allocation and thus don't have to worry about OOM. This profile is perfectly usable for writing kernels, and could also be used to write an alternate kernel-specific stdlib which make it possible to handle OOM. > Complaining about the existence of Parse is like > complaining about the existence of unwrap in Rust. This is mistaken. Complaining about Parse would only be like complaining about unwrap if unwrap were the implicit and default behavior. Parse throws implicitly, but unwrap doesn't get called implicitly. The fact that the possibility is impossible to accidentally overlook is an enormous and crucial difference.
- detrino 11y agoOvercommit is just one configuration on Linux, it is a good default, but there are domains where you would disable it. How is Parse any less explicit than unwrap ?
- kibwen 11y agoParse is less explicit than unwrap because the following C# code is legal: uint foo = uint.Parse("3"); But the following Rust code is not legal: let foo: u32 = "3".parse(); // error: mismatched types It's impossible to use the return value of parse as though it's a u32, because it's not a u32. You can't accidentally add it to some other number or use it to index an array, because it's the wrong type entirely. You invariably must acknowledge the possibility of failure, and if you're okay with terminating your thread in the event of an error you can do this via an unwrap: let foo: u32 = "3".parse().unwrap(); // just fine Rust's parse is even more explicit than C#'s TryParse, because even with TryParse it's possible to forget to check the return value: uint foo; uint.TryParse("Hello", out foo); // this compiles and runs! And it's not just about string parsing. The overarching point here is that not only does the compiler protect you from errors that you know about, it also brings your attention to errors that you didn't know about. The OP has a great example in that it's very easy to forget that the `min` method on vectors can fail if that vector is empty. Finally, this assurance extends in the other direction as well: knowing that libraries are architected to make errors explicit via return types means that if I don't get yelled at for not handling a return type, then I have peace of mind knowing I'm not overlooking anything. This is somewhat analogous to the considerable assurance given in knowing that types aren't implicitly nullable. Now, if you're looking for something that can still go wrong, there's a better example then OOM: dividing by zero in Rust will implicitly panic. So while it's unlikely that a library author will use unwrap in their code (there's a strong culture against Rust libraries causing panics), it's possible that a library author could accidentally cause a panic by dividing by zero.
- detrino 11y agoBoth Rust and C# provide throwing/failing interfaces for parsing, it's just that Rust's is written: let foo: u32 = "3".parse().unwrap(); and C#'s is written: var foo = uint.Parse("3"); Both require familiarity with the stdlib (Parse throws, TryParse doesn't, unwrap fails). I agree that TryParse is worse than Rust's ADT approach, but that's a different issue, much like nullable references. The author is asserting that results are superior to exceptions and I am asserting that no, that is just a bad application of exceptions. Additionally, I am asserting that without exceptions, you limit what programmers are willing to propagate through their interfaces because errors become viral.