Earlier quoted context omitted.
Using exceptions solves that problem and many others besides; it's a shame they're not currently in fashion. But you do end up needing them, so in Rust, we end up with error codes _and_ exceptions (but spelled "panic").
I wouldn't call panic the same thing as exceptions - panics are quite explicitly meant to not be caught, except at fairly hefty boundaries like processes, threads, or FFI. Using std::panic::catch_unwind to catch, say, accessing an out-of-bounds element in a vector would be super un-idiomatic, both because that's what .get() -> Option is for, and also because even if you catch the panic, the message gets printed to st…
Redox OS Crash Challenge
61–70 of 82 posts
Re: Redox OS Crash Challenge
#62Earlier quoted context omitted.
Using exceptions solves that problem and many others besides; it's a shame they're not currently in fashion. But you do end up needing them, so in Rust, we end up with error codes _and_ exceptions (but spelled "panic").
Well, error codes are not special constructs in any way. And exceptions can be easily overused. So you have to draw the line somewhere. Rust just choose the balance where facing an exception is truly exceptional :)
We've long since past the time that we have to worry about such concerns. "Exceptions for exceptional errors" just means that you have to write code that both cares about exception safety and propagates error codes from subroutines. It's the worst of both worlds.
Just use exceptions for all errors. It's elegant.
Re: Redox OS Crash Challenge
#63Earlier quoted context omitted.
The idea that something can be "necessary but not sufficient" comes up a lot, and is very often misunderstood. Rust-like guarantees are necessary but not sufficient for safe systems.
As DJB and other excellent programmers have demonstrated, they're not strictly necessary either. (and I really like Rust)
Re: Redox OS Crash Challenge
#64Earlier quoted context omitted.
Rust is significantly different with regards to this stuff: * There is no reflection API * Exceptions don't exist * There's no subtyping, so ClassCastExceptions can't exist. (There's subtyping with lifetimes, and you can't cast them, so that doesn't count) * final doens't exist That said, every language has things that you don't realize; we did have a sort of similar moment to this stuff before 1.0 with the "leakapoc…
> Exceptions don't exist They're called panics. > There's no subtyping, so ClassCastExceptions can't exist. Any sort of polymorphism opens you up to the possibility that code that's written to take abstract type A, implemented concretely in B and C, implicitly expects a B and blows up when it gets a C. Rust doesn't solve this problem. > final doens't exist Sure it does. It's just implied, and not-final has to be spel…
Nope.
Re: Redox OS Crash Challenge
#65Earlier quoted context omitted.
I wouldn't call panic the same thing as exceptions - panics are quite explicitly meant to not be caught, except at fairly hefty boundaries like processes, threads, or FFI. Using std::panic::catch_unwind to catch, say, accessing an out-of-bounds element in a vector would be super un-idiomatic, both because that's what .get() -> Option is for, and also because even if you catch the panic, the message gets printed to st…
In other words, Rust _does_ have exceptions! That some people don't use them all that much is a matter of convention in a particular community, not a matter of language feature set. You could implement exactly the same model in C++. The fact is that Rust has exceptions to exactly the same extent C++ has them.
I don't really see a huge distinction between a language and its community, for the primary reason that feature evolution in a language - e.g., that Results recently got the question-mark operator, and whether Results will get "throw"/"catch" syntax - is driven by the language community and what sorts of things are or aren't common practice. A Rust community that made heavy use of panics in normally-operating code would probably want to fork Rust just to optimize panicking and catching panics, to fix the fact that catch_unwind is documented to not necessarily catch all panics, etc., and would eventually make deeper language changes to improve the syntax around doing panicking and not merge the corresponding changes to improve the syntax around Result. Which is historically what's happened with languages that have developed multiple communities - there are lots of Lisp dialects, lots of BASIC dialects, etc. Whether BASIC has a feature isn't a well-formed question; whether GW-BASIC or VB.NET or your TI-83 has a feature is well-formed.
Re: Redox OS Crash Challenge
#66Earlier quoted context omitted.
Well, error codes are not special constructs in any way. And exceptions can be easily overused. So you have to draw the line somewhere. Rust just choose the balance where facing an exception is truly exceptional :)
"Exceptions are for exceptional conditions" is a meme that I wish would just die. Its origin lies in 1990s C++ compilers, which were extremely inefficient when dispatching exceptions, leading programmers, as a pragmatic measure, to use error codes for "expected" errors and exceptions only for cases thought to occur infrequently. We've long since past the time that we have to worry about such concerns. "Exceptions for…
Java has a particularly inelegant and ugly solution here involving declaring what types of exceptions might be thrown. But that still doesn't change the fact that changing that list is an API change, it just makes it more explicit.
So if you care about API stability (and I firmly believe that no solution that ignores API stability is "elegant" - it is at best "cute"), you're basically required to catch the vast majority of exceptions your own dependencies generate and translate them to your own exception types. You'll need to make a MyHTTPLibCertificateValidationError, unwrap the contents of OpenSSLValidationError, and put them in the new object, or you can never switch away from OpenSSL without an API break. And you want your dependencies to follow the same discipline.
At that point, as I said above, why use unwinding? None of the exceptions in your program can safely pass more than one level of the call stack at a time; each level has to explicitly approve raising it another level or wrap the exception in its own type (or handle it). The only ones that can really unwind are standard library ones like OutOfMemoryError that are expected to go all the way up the call stack to the top of the program or at best the top of the current request, print or otherwise log a backtrace, and abort the entire thing in progress - i.e., exceptional conditions. Exceptions for expected conditions are a different thing entirely, precisely because you don't want unwinding, you want step-by-step propagation.
This has nothing to do with efficiency. This has to do with correctness and robustness.
And you get your syntactic elegance with a library for translating and wrapping error objects, like https://docs.rs/error-chain , combined with syntax for immediately translating and returning errors from dependencies, like https://doc.rust-lang.org/book/second-edition/ch09-02-recove... .
Re: Redox OS Crash Challenge
#67Earlier quoted context omitted.
> Exceptions don't exist They're called panics. > There's no subtyping, so ClassCastExceptions can't exist. Any sort of polymorphism opens you up to the possibility that code that's written to take abstract type A, implemented concretely in B and C, implicitly expects a B and blows up when it gets a C. Rust doesn't solve this problem. > final doens't exist Sure it does. It's just implied, and not-final has to be spel…
> > Exceptions don't exist > > They're called panics. Nope. https://doc.rust-lang.org/std/panic/fn.catch_unwind.html
Sure, it's not "recommended", but recommendations don't define semantics.
Re: Redox OS Crash Challenge
#68Earlier quoted context omitted.
Well, error codes are not special constructs in any way. And exceptions can be easily overused. So you have to draw the line somewhere. Rust just choose the balance where facing an exception is truly exceptional :)
"Exceptions are for exceptional conditions" is a meme that I wish would just die. Its origin lies in 1990s C++ compilers, which were extremely inefficient when dispatching exceptions, leading programmers, as a pragmatic measure, to use error codes for "expected" errors and exceptions only for cases thought to occur infrequently. We've long since past the time that we have to worry about such concerns. "Exceptions for…
Some compilers even won't let you use them without turning on full-blown RTTI(or doing it implicitly for you) which is even worse.
Re: Redox OS Crash Challenge
#69This was the output I got when I followed the instructions from the book: - what should I have seen? Can you suggest what I can do to make it work? (venv3.5) root@ubuntu-s-1vcpu-1gb-nyc1-01:~# qemu-system-x86_64 -serial mon:stdio -d cpu_reset -d guest_errors -smp 4 -m 1024 -s -machine q35 -device ich9-intel-hda -device hda-duplex -net nic,model=e1000 -net user -device nec-usb-xhci,id=xhci -device usb-tablet,bus=xhci.…
Re: Redox OS Crash Challenge
#70Earlier quoted context omitted.
> like forgetting to check error returns One of the most common bugs in C (in my experience) is forgetting to check the error return on a malloc call. Kind of the worst of both worlds.
Yes! In fact I'd argue that null-pointer dereferences are not a memory-safety bug the way buffer overflows / use-after-frees / etc. are, they're a type-safety bug. It's not that NULL is a currently-invalid pointer, it's that NULL is not a pointer at all - it's a value that's been stuffed into the pointer type because C has no better way to represent this. The actual return type of malloc is the set of all possible po…