back

by uecker·7mo ago·view on hn ↗
I agree that C is best. I think Rust is actually a language with some severe downsides, despite having including some very good ideas and C having some real issues. But it will take a couple of years before one can discuss this rationally without being flamed at.
2 comments
If you want to spread this idea, it would probably help your cause if you pointed to what you think Rust does particularly poorly. Steep learning curve, npm-esque packaging?
The article gave many good reasons where Rust is lacking. The points you raise are also clearly issues. My main additional issues are the high complexity, the syntax, the lack of stability, compilation times (and monomorphization), and lack of alternate implementations. Ignoring the language itself, the aggressive and partially misleading negative and positive marketing.
Lack of (useful) dynamic linking is a huge problem IMO.
What do you mean by useful dynamic linking? Dynamic linking with C ABI is supported natively in Rust and is very widely used (just checked GitHub), especially for FFI like in Python modules (PyO3). If you mean an ABI that supports all the Rust features (without extern C), then it's a problem faced by every language that has more features than C - C++, Haskell, Go, Zig, etc included. To solve that problem, somebody will have to design a new stable standard common ABI that natively supports all the features from these languages, or at least makes it possible to express these features in some way.
C++ has reasonable dynamic linking (there are ABI breaks, but I only remember only one really bad one with std::basic_string and C++11), obviously excluding a lot of metaprogramming features, but a lot of C++ dynamic libraries exist that are widely used. Supposedly Swift does a better job, though I'm not familiar. Yes, Rust can dynamically link with a C ABI (as can any language) but it loses a lot of the expressiveness (I imagine, I'm not a rust developer) to have to use the C ABI.

Dynamic languages of course support dynamic linking.

> there are ABI breaks, but I only remember only one really bad one with std::basic_string and C++11

ABI breaks are everywhere in C++... consider a class

  class foo {
  public:
    foo();
    void do_something();
  private:
    int x;
  }
and an impl in the dynamic library:

  #include "foo.h"
  foo::foo() {
    this->x = 0;
  }
  void foo::do_something() { std::cout << this->x << std::endl; }
You build a libfoo.so and clients use it, calling `foo f; f.do_something();`, it calls your library and it's great.

But as soon as you ship a new version that adds a new field to foo (still source-code compatible):

  class foo {
  public:
    foo();
    void do_something();
  private:
    int x;
    int y;
  };
With a new function body in your shared object:

  void foo::do_something() { std::cout << this->x << this->y << std::endl; }
You're hosed. Clients have to recompile, or they get:

  $ ./main
  0, 0
  *** stack smashing detected ***: terminated
  [1]    2625391 IOT instruction (core dumped)  ./main
Because the size information for an instance of foo is only known at compile-time, so the clients aren't allocating enough space on the stack for it (ditto the heap if you're using `new foo();`)

The way around this is awkward and involves the pimpl pattern and moving all your constructors out-of-line... but you also need to freeze all virtual methods (even just adding a new one breaks ABI), and avoid using any template-heavy std:: types (not even std::string), since those are often fragile.

Most people just give up and offer an extern "C" API, because that has the added benefit that it's compatible across compilers.

"true" C++ shared libraries are crazy difficult to maintain. It's the reason microsoft invented COM.

Swift goes through crazy lengths to make this work, and it's impressive: https://faultlore.com/blah/swift-abi/#resilient-type-layout

Rust would have to do something like Swift is doing, and that's probably never going to happen.

Sure, you can break ABI in a library, but the compiler doesn't force you to, is what I mean. Same as breaking ABI in C when you change a struct...
It is problem of all languages whose extensions to C are badly designed. That it works with the C FFI just shows that C part properly supports it while Rust does not. And yes, C++ has similar problems as Rust.
Both Pin Projection and the handling of async are pretty bad in my opinion and I write a lot of Rust code. The syntax is also slowly getting very funky with horrible additions like the recent `+ use <'a>` snytax. I also agree with the orphan rule but it makes a lot of code very ugly, fast.
> Rust is actually a horrible language

Can you expand a little?

They never said it's a horrible language.
The original comment was edited after I replied.
Yes, sorry, apparently not quick enough. I actually do not think it is horrible. It is a nice language, but I still do not like it and see many downsides. What I hate though is how aggressively it is marketed. See my other response for details.
That is fair. Rust is my most used language, and I agree Rust has many downsides and pain points. But for my work, the positives outweigh the downsides of other languages I've used (including Python, Java, C++, and C).

But it ultimately depends on your situation. People elsewhere on this post are listing weaknesses of Rust that I consider to be strengths and vice versa.

Nobody is marketing it. It doesn't have a marketing budget. What you're seeing are lots of people that really like it because it's really good. Not flawless obviously but a significant improvement on C and C++.
I see a lot of activity of very specific parts of the industry promoting it. But also enthusiasts doing aggressive marketing are doing aggressive marketing - even if they do not have a budget. Whether it is an improvement is debatable. From my perspective, it is an improvement in some aspects and a significant step back in others. What is unacceptable though is the significant hate and pressure towards people who have other priorities and preferences, which is created by the "we must stamp out memory safety issues at all cost and Rust is the solution" narrative.
> Whether it is an improvement is debatable.

Not really.

> it is an improvement in some aspects and a significant step back in others

Of course. Very few improvements are better in every way. There's always something you can find to like about the old solution. Horses are friendlier than cars. Records allow bigger artwork than CDs. Unlike DVDs (at first anyway) you can write to VHS. Unlike Typescript, Javascript doesn't need a compile step. FORTRAN77 fits nicely on punch cards.

That doesn't mean there's really any serious debate about them being improvements.

I will freely admit that Rust has only average compile time (though it's better than C++ at this point), high complexity, and async Rust is full of footguns. But I could come up with a much longer list of complaints for C.

> we must stamp out memory safety issues at all cost and Rust is the solution

Yeah I think memory safety is actually probably not the most important thing about Rust. Having a modern strong type system is arguably more significant. Memory safety is important too of course - even if you don't care about security memory safety issues are often plain hard to debug bugs.