Live data from Hacker News

Matt Godbolt sold me on Rust by showing me C++

collabora.com

111–120 of 675 posts

Re: Matt Godbolt sold me on Rust by showing me C++

#111
post #8

The one thing that sold me on Rust (going from C++) was that there is a single way errors are propagated: the Result type. No need to bother with exceptions, functions returning bool, functions returning 0 on success, functions returning 0 on error, functions returning -1 on error, functions returning negative errno on error, functions taking optional pointer to bool to indicate error (optionally), functions taking r…

unfortunately it's not so simple. that's the convention. depending on the library you're using it might be a special type of Error, or special type of Result, something needs to be transformed, `?` might not work in that case (unless you transform/map it), etc. I like rust, but its not as clean in practice, as you describe

There are patterns to address it such as creating your own Result type alias with the error type parameter (E) fixed to an error type you own:

    type Result = result::Result;

    #[derive(Debug)]
    enum MyError {
        IOError(String)
        // ...
    }
Your owned (i.e. not third-party) Error type is a sum type of error types that might be thrown by other libraries, with a newtype wrapper (`IOError`) on top.

Then implement the `From` trait to map errors from third-party libraries to your own custom Error space:

    impl From for MyError {
        fn from(e: io::Error) -> MyError {
            MyError::IOError(e.to_string())
        }
    }
Now you can convert any result into a single type that you control by transforming the errors:

    return sender
        .write_all(msg.as_bytes())
        .map_err(|e| e.into());
There is a little boilerplate and mapping between error spaces that is required but I don't find it that onerous.

Re: Matt Godbolt sold me on Rust by showing me C++

#112

Earlier quoted context omitted.

> The one thing that sold me on Rust (going from C++) was that there is a single way errors are propagated: the Result type. No need to bother with exceptions This isn't really true since Rust has panics. It would be nice to have out-of-the-box support for a "no panics" subset of Rust, which would also make it easier to properly support linear (no auto-drop) types.

It's pretty difficult to have no panics, because many functions allocate memory and what are they supposed to do when there is no memory left? Also many functions use addition and what is one supposed to do in case of overflow?

Additions are easy. By default they are wrapped, and you can make them explicit with checked_ methods.

Assuming that you are not using much recursion, you can eliminate most of the heap related memory panics by adding limited reservation checks for dynamic data, which is allocated based on user input/external data. You should also use statically sized types whennever possible. They are also faster.

Re: Matt Godbolt sold me on Rust by showing me C++

#113
post #8

The one thing that sold me on Rust (going from C++) was that there is a single way errors are propagated: the Result type. No need to bother with exceptions, functions returning bool, functions returning 0 on success, functions returning 0 on error, functions returning -1 on error, functions returning negative errno on error, functions taking optional pointer to bool to indicate error (optionally), functions taking r…

Proper error handling is the biggest problem in a vast majority of programs and rust makes that straightforward by providing a framework that works really well. I hate the `?` shortcut though. It's used horribly in many rust programs that I've seen because the programmers just use it as a half assed replacement for exceptions. Another gripe I have is that most library authors don't document what errors are returned in what situations and you're left making guesses or navigating through the library code to figure this out.

Re: Matt Godbolt sold me on Rust by showing me C++

#114

Earlier quoted context omitted.

> The one thing that sold me on Rust (going from C++) was that there is a single way errors are propagated: the Result type. No need to bother with exceptions This isn't really true since Rust has panics. It would be nice to have out-of-the-box support for a "no panics" subset of Rust, which would also make it easier to properly support linear (no auto-drop) types.

It's pretty difficult to have no panics, because many functions allocate memory and what are they supposed to do when there is no memory left? Also many functions use addition and what is one supposed to do in case of overflow?

Don't know about your parent poster but I didn't take it 100% literally. Obviously if there's no memory left then you crash; the kernel would likely murder your program half a second later anyway.

But for arithmetics Rust has non-aborting bound checking API, if my memory serves.

And that's what I'm trying hard to do in my Rust code f.ex. don't frivolously use `unwrap` or `expect`, ever. And just generally try hard to never use an API that can crash. You can write a few error branches that might never get triggered. It's not the end of the world.

Re: Matt Godbolt sold me on Rust by showing me C++

#115

Earlier quoted context omitted.

that's kind of a thing with https://docs.rs/no-panic/latest/no_panic/ or no std and custom panic handlers. not sure what the latest is in the space, if I recall there are some subtleties

That's a neat hack, but it would be a lot nicer to have explicit support as part of the language.

The problem is with false positives. Even if you clearly see that some function will never panic (but it uses some feature which may panic), compiler might not always see that. If compiler says that there are no panics, then there are no panics, but is it enough to add as part of the language if you need to mostly avoid using features that might panic?

Re: Matt Godbolt sold me on Rust by showing me C++

#116
post #48

Earlier quoted context omitted.

> The one thing that sold me on Rust (going from C++) was that there is a single way errors are propagated: the Result type. No need to bother with exceptions This isn't really true since Rust has panics. It would be nice to have out-of-the-box support for a "no panics" subset of Rust, which would also make it easier to properly support linear (no auto-drop) types.

`panic` isn’t really an error that you have to (or can) handle, it’s for unrecoverable errors. Sort of like C++ assertions. Also there is the no_panic crate, which uses macros to require the compiler to prove that a given function cannot panic.

Well, kinda. It's more similar to RuntimeException in Java, in that there are times where you do actually want to catch and recover from them.

But on those places, you better know exactly what you are doing.

Re: Matt Godbolt sold me on Rust by showing me C++

#118

Earlier quoted context omitted.

that's kind of a thing with https://docs.rs/no-panic/latest/no_panic/ or no std and custom panic handlers. not sure what the latest is in the space, if I recall there are some subtleties

That's a neat hack, but it would be a lot nicer to have explicit support as part of the language.

That's going to be difficult because the language itself requires panic support to properly implement indexing, slicing, and integer division. There are checked methods that can be used instead, but to truly eliminate panics, the ordinary operators would have to be banned when used with non-const arguments, and this restriction would have to propagate to all dependencies as well.

Re: Matt Godbolt sold me on Rust by showing me C++

#119
post #91

Earlier quoted context omitted.

would you consider panics acceptable when you think it cannot panic in practice? e.g. unwraping/expecting a value for a key in a map when you inserted that value before and know it hasn't been removed? you could have a panic though, if you wrongly make assumptions

I don't speak for anyone else but I'm not using `unwrap` and `expect`. I understand the scenario you outlined but I've accepted it as a compromise and will `match` on a map's fetching function and will have an `Err` branch. I will fight against program aborts as hard as I possibly can. I don't mind boilerplate to be the price paid and will provide detailed error messages even in such obscure error branches. Again, sp…

> the program is no good for me dead

That may be true, but the program may actually be bad for you if it does something unexpected due to an unforeseen state.

Re: Matt Godbolt sold me on Rust by showing me C++

#120

Earlier quoted context omitted.

Absolutely, the compile times are the biggest drawback IMO. Everywhere I've been that built large systems in Rust eventually ends up spending a good amount of dev time trying to get CI/CD pipeline times to something sane. Besides developer productivity it can be an issue when you need a critical fix to go out quickly and your pipelines take 60+ minutes.

Don't use a single monolithic crate. Break your project up into multiple crates. Not only does this help with compile time (the individual crate compiles can be parallelized), it also tends to help with API design as well.

Every project I've worked on used a workspace with many crates. Generally that only gets you so far on large projects.
Post reply on HN