That is, in terms of safety, this is the same thing as explicitly handling the error and then terminating the process. Which is the only real way you're going to handle this error anyway, unless you wanted some sort of retry logic. Which you might!
That is, in terms of safety, this is the same thing as explicitly handling the error and then terminating the process. Which is the only real way you're going to handle this error anyway, unless you wanted some sort of retry logic. Which you might!
But for most example programs there's no easy way to handle errors further than just using expect() unless you want there to be more error handling code than actual useful example code.
The idea is that I expect this to be Ok/Some, and if it's not, please use this error message.
Here, the programmatic object is the grammatical object. That's what I meant by 'backwards'.
could_fail().or_panic_with('message') may be even better.
unwrap should be confined to test and temporary code. It somewhat makes sense in example code, but expect is better for that.
There are sometimes cases when you very easily know that the unwrap will never fail and if it does something has gone very horribly wrong, in which case you might use it.
Libraries should keep usage of unwrap/expect to a minimum. Applications can be more liberal with it, but they should try to use expect or better error handling.
Not everyone perfectly follows this, sadly. But most do.
This will print an error out already.
$ ./target/debug/tokiotest
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error { repr: Os { code: 98, message: "Address already in use" } }', ../src/libcore/result.rs:837
Printing out a _better_ error might be helpful, though, I'll agree :) You could use expect for that, which lets you change the message in the ''s easily.This really shows a fundamental tension though, in documentation. Is this example supposed to be demonstrating error handling? Or just get you going? Does adding more complex error handling distract from the point it's trying to teach? These are sort of open-ended questions.
As I said in the post you're replying to, a nicer error message would be a good thing.
Whoever maintains the server and runs the service is also my user, though, in the general case.
> As I said in the post you're replying to, a nicer error message would be a good thing.
Yeah - I don't mind if unwrap panics with a dev-oriented message as it's basically an assertion, but I guess I expected expect() (no pun intended) to give a more user-friendly error. Maybe the format of the panic! output could be changed to bring the message to the front and the technical details after that.
Obviously not if it's used for input errors (network failure). Crashing assertions are made for bugs, not input errors.
We can agree in the cynical interpretation of the laziness of programmers, but the mitigations in this case are so trivial, and the stakes so low, that focusing on unwrap as a point of contention is a poor use of energy.
If rust had that examples would be even shorter using ? Instead of try! or unwrap
`quick_error` uses a trait like that to determine the exit code of `main()`, allowing it to return either () or i32.
quick_main!(|| -> Result<()> {
// insert Result-returning code here
});
Alternatively it takes a few lines to bootstrap it by hand e.g. ripgrep uses this code to bootstrap: fn main() {
match Args::parse().map(Arc::new).and_then(run) {
Ok(0) => process::exit(1),
Ok(_) => process::exit(0),
Err(err) => {
eprintln!("{}", err);
process::exit(1);
}
}
}
https://github.com/BurntSushi/ripgrep/blob/master/src/main.r...http://rust-lang.github.io/book/ch12-03-improving-error-hand... shows how to refactor a project to improve its error handling as well, for something a bit less abstract.
Such error handling code is usually untested, which is another way of saying 'buggy'. It almost always swallows useful information, like the backtrace. It sometimes lets program execution continue in a messed up state, causing very strange and hard to debug errors later on.
Certainly Rust makes it a lot harder to mess up error handling code than the languages I'm used to but in general I'm definitely in the 'all exceptions fatal' camp.
* Rust prevents deadlocks
* You can't leak memory in Rust
* Rust prevents race conditions
* Panic is not safe
etc. In my mind, bringing up memory safety here isn't a red herring; the parent said this:
> However Rust is billing itself as a safe systems programming alternative to C and C++.
The way in which we are safer is memory safety, nothing more. And knowing that is crucial.
Rust code will have bugs. Rust code will have security vulnerabilities. Rust is not a panacea.
I know you want to not overstate rust's claims given recent articles, but I think you're actually underselling a little here. For example, a rust `enum` make it much easier for the compiler to enforce code correctness. It's hard to go back to similar code in C or Go once you've gotten used to `match`.
> prevents segfaults
Only outside unsafe blocks.
> guarantees thread safety.
But you just said you can have deadlocks and race condition, so... perhaps change the frontpage?
The page clarifies later on that the definition of thread safety in question is "threads without data races." The 16 words on the front page of the website are not the appropriate place to go into caveats and nuances.
> Only outside unsafe blocks.
This is just true of all of our guarantees. Given that the vast, vast, vast, vast majority of Rust code is safe code, I don't feel this is misleading. Do you say that Ruby doesn't prevent segfaults due to its C FFI?
edit: I'm just saying "don't lie". I shouldn't have to defend this view point and get downvotes for it.
1/ It says on the tin "prevents segfaults". It does not prevent segfaults in all cases, but OK, let's debate the other claim.
2/ It also says "guarantees thread safety". What is the Wikipedia definition of thread safety? It varies, so let's take the most common "freedom from race conditions."
Steve come and say Rust can have race conditions https://news.ycombinator.com/item?id=13376485 and that it's a common misunderstanding to think it prevents race conditions. Surely it would be great if the frontpage would not promote it!
Ergo the frontpage claim is false.
The wikipedia definition is pretty vague, it relies on a concept of "safe" that isn't defined there. It's acceptable to say that "data race safety" is "thread safety", though confusing. Rust's homepage does clarify what it means in the bullet points below that statement, so I wouldn't call this a lie. It may be misleading though, and this is a common misunderstanding as steve mentioned, so I submitted a PR to fix it https://github.com/rust-lang/rust-www/pull/685
In the punchline, "prevent segfaults" is framed in negative terms. If you put "provides memory safety" it will be a bit less evocative of specific pain, but will give a warm feeling.
Not too sure of the segfaults bit, feel free to put in your thoughts on that PR
Rust is a systems programming language that runs blazingly fast, guarantees memory safety and provides correct concurrency.
Rust is a systems programming language that provides uncompromised performance, convenience and security.
Rust is a systems programming language that enables unprecedented levels of performance, productivity and safety.
edit: I like (2) best
This is a relatively uninteresting quibble: the guarantees of any language only apply outside their equivalent of unsafe blocks (e.g. Python is memory safe... until you use ctypes). Pretty much everything has a way to FFI down to interact with the machine; in Rust, it's just called `unsafe`.
(One way to look at `unsafe` is that it's a tightly integrated FFI to another language called "unsafe Rust", and it benefits from having zero performance or semantic overhead.)
If a language frontpage is inexact I'll assume the rest of the website is inexact, simple as that.
Terminology matters.
As it cost me 20+ downvotes to make a rational conversation with you all, I will stop interacting with the Rust community.
As I mentioned in https://news.ycombinator.com/item?id=13377957, in the world of programming languages, the term "memory safety" means something specific.
D calls itself safe on its website, but it too has the ability to escape-hatch into C/C++.
Language websites putting forth subjective claims or claims based on definitions which may be subjective is totally normal:
Go says that it "makes it easy to build simple, reliable, and efficient software", which is totally subjective.
Ruby says "It has an elegant syntax that is natural to read and easy to write.", also subjective.
Python says "lets you work quickly and integrate systems more effectively", also subjective.
By the same token, you should be requiring that every subjective statement on the other langs' pages have the caveat "in the opinion of the $LANG developers." Obviously no one would wear that.
While teaching Rust it's a recurring theme among students to believe that all crashes are created equal and that an exit from a panic must be equivalent to a segfault, despite this being significantly false. So it's common when discussing panics to novice audiences to sprinkle in "by the way, this isn't a crash, it's a controlled exit".
Is it? It's out of bounds of any object, and therefore undefined behavior.