Re: The Case for Rust (in any system)

From: Alan Somers <asomers_at_freebsd.org>
Date: Thu, 12 Sep 2024 21:52:46 UTC
Thank you!  This is some of the best criticism I've seen so far.

On Thu, Sep 12, 2024 at 1:25 PM Yuri <yuri@freebsd.org> wrote:
>
> Hi Alan,
>
>
>
> No, I don't think that Rust delivers on its promises.
>
>
> I program all the time, on a daily basis.
>
>
> Rust has many very serious shortcomings:
>
>
> 1. Rust doesn't have exceptions. In practice this means that the
> programmer needs to manually write a lot of code to handle all sorts of
> failure conditions in complex code. This leads to a lot more code being
> necessary to achieve the same project objectives. When in C++ an
> exception is simply thrown and caught, in Rust you have to write all the
> underlying checks manually. I know from practice that the number of bugs
> is roughly proportional to the amount of code.

No doubt Yuri already knows the following, but I'll explain it for
other readers' sake. I too have used to use exceptions in C++, Java,
Python, and Ruby.  The problem with exceptions is that you can never
know what errors your function might have to deal with.  You can add
error handling for every exception type that you know about, but
there's nothing to prevent some lower-level library function from
throwing an entirely new exception that you've never heard of.  When
that happens, your program will crash with "uncaught exception".  The
problem is worst in Python, but it affects C++, too.  C++'s solution
to that problem was checked exceptions.  A function would document in
its signature all of the exception types that it might throw, and the
compilation will fail if the code attempts to throw any new ones.
That way, consumers could be confident that they could handle all
possible errors.  The problem with this approach is that lower-level
libraries frequently added new exception types, with the result that
their consumers' builds would frequently fail.  That's why C++11
deprecated checked exceptions.

That's one of the reasons why Rust doesn't implement exceptions (the
other, IIRC, being performance).  Instead, Rust functions report
errors in their output types, like in C.  But unlike C, Rust employs
enum types for error reporting.  Chiefly, the Result type.  So unlike
C++11, errors are a part of the type system, but unlike C there's a
clear distinction between errors and successful return values.  And
consumers can confidently handle enumerate every possible error that a
function might return.  If a consumer isn't able to intelligently
handle some cases, the usual pattern is to either panic or pass them
up the stack.

You might be asking "doesn't that have the exact same problem that
checked exceptions have?" It does, basically.  But there's one final
detail: a Rust enum can declare itself to be #[non_exhaustive].  Most
error types do that.  That prevents a consumer from attempting to
exhaustively match the error types, forcing them to add a default
action (usually either panic or pass up-stack).  With an enum so
declared, its maintainer is free to add new values at any time.

Now you might be asking "doesn't that have the exact same problem that
unchecked exceptions have"?  It does, basically.  But at least a
consumer always knows the type of the errors that it must handle.
That's not true of unchecked exceptions in C++, where absolutely any
type of Exception might arrive.

So the two systems, exceptions vs Result types, aren't too different.
Having learned the latter, I'm now comfortable with them.  I prefer
them even, though that's a matter of opinion.

>
>
> 2. The Rust code might not cause segmentation faults, but during error
> processing the programmer often has to write wrap() functions which fail
> with error messages practically equivalent to segmentation faults in
> C/C++. The end result is the same for the user - the process fails or
> aborts in the middle.

Again for other readers' benefit, Yuri is talking about the unwrap()
and expect() methods, which transform errors into panics.  Those are
typically used for unhandled errors, where a C programmer might call
err(3) or exit(3).  They aren't really equivalent to segfaults, which
result from memory handling mistakes.

> 3. The code written in Rust is a lot less expressive. What can be
> expressed with a very short and elegant C++ code in Rust has to be
> written in a lot more explicit way with a lot more lines. I practically
> experienced this with the Rust Ratatui TUI library when everything takes
> a lot more lines compared to an equivalent FTXUI C++ TUI library.

Like Yuri I've used Ratatui in Rust.  But unlike Yuri I haven't
written any TUIs in C or C++.  For my education, could you point me to
some examples?  Something that FTXUI is particularly good at?

> The above 3 shortcomings makes Rust a no-go solution for me.
>
>
> Not long ago I tried to write a TUI program using Rust and I found the
> hard way that it is simply a lot easier to achieve with C++ and FTXUI
> than with Rust and Ratatui.
>
>
> There are nice things about Rust too. One nice thing is that Rust has a
> nice development ecosystem when all Rust packages are registered in one
> place, and are discoverable in the same fashion, unlike C++ packages
> that are all over the place.
>
>
> Investors, especially fintech investors, get sold on Rust because they
> believe that the Rust code is a lot safer. But these investors are not
> engineers themselves, and they have no first hand experience with Rust.
> They simply rely on opinions of others. Fintech startups use Rust as a
> selling point for their enterprises. The more selling points they list -
> the more likely they get an investment. Everything helps when it comes
> to this.
>
>
> Given the above shortcomings, Rust in practice is not a better language
> overall.
>
>
> Please just put this idea to rest.
>
>
> Thanks, but no thanks.
>
>
>
> Yuri
>
>