← Back to context

Comment by beeflet

6 months ago

rust has other advantages. I think cargo is better than cmake. I think the syntax is better, I think the way dependencies and modules are handled is better.

It can be annoying to write "safe" code, but once it meets a certain standard I can be confident in multithreaded applications I write.

I would like to use rust to write android apps. I don't really like the whole android studio java thing.

> I think cargo is better than cmake

I expect that Google is using neither of these for most of their own code, but rather their own build system (which I think is the same between the languages).

I absolutely agree if you aren't Google though.

>I think cargo is better than cmake

That is an understatement. I can't think of a build system that has spawned more attempts to find something better than CMake has.

There have been so many people trying to make their own C/C++ build system and/or package manager out of sheer spite for CMake that it's frankly hard to keep track.

In fairness to them and to CMake, it's not a simple problem to solve. To truly know CMake is to wish you didn't, that way someone else would have to maintain it.

  • You seem to forget about autotools. Cmake is ugly but I'll take it over autotools.

    • As an end user: at least with autotools it's easy for me to see the available configuration options with ./configure --help in a nicely readable way. cmake has -LAH but it's still... kind of awful.

      At least it knows how to use ninja though.

      4 replies →

I cannot like Rust syntax, sorry.

For me the ideal syntax is C/Go, just to be clear what I like.

But I agree that the tooling that cargo introduced is a breath of fresh air in a world dominated by huge makefiles, libraries copied in the repository (I know, there is Conan, vcpkg etc)...

  • > I cannot like Rust syntax, sorry. For me the ideal syntax is C/Go, just to be clear what I like.

    I’m sorry if this comes across as dismissive, but I find it hard to take people seriously with complaints about syntax like this. Learning new syntax is really easy. Like, if you’re familiar with C & Go, you could probably learn all the syntax of rust in under an hour. The only surprising part of rust’s syntax is all the weird variants of match expressions.

    Rust has some surprising semantics. Like how lifetimes work (and when you need to specify them explicitly). That stuff is legitimately difficult. But learning that if statements don’t need parenthesis is like - seriously whatever dude. If you want to spend your career never learning new stuff, software isn’t for you.

    I picked up objective C about 15 years ago. The only thing most of my friends knew about it was that it had “that weird syntax”. It took no time at all to adjust. It’s just not that hard to type [] characters.

    • I'm very vocal that I don't like Python syntax, but I wouldn't refuse to write Python because of the syntax. If I had reason to write Python, I would grumble a bit but write the Python.

    • I'd say that rust has a weird level of being both verbose and terse in strange ways.

      If you ever have to deal with lifetimes, then the verbosity goes up pretty significantly. And, dealing with pointers ultimately introduces multiple layers of concepts that you don't necessarily run into with C++/Go/Java.

      Yet, with the type inference by default, rust can often feel shockingly terse. Doing collection manipulation is just as terse as any language you could imagine.

      I think that's probably where complaints about syntax comes in.

      C++ hides a lot of that complexity with move semantics, shorthands, autocoersion, and by making lifetime issues runtime problems. Languages like Go/Java/Python simply push everything onto the heap and try to avoid exposing low level memory semantics.

      It's easy for me to see why someone wouldn't like rust. I think it's fine, but I'm also brain broken from perl and php.

      1 reply →

    • It's not about learning syntax, it's about finding it generally tolerable to read. I personally find Rust syntax repulsive and would opt for a different language unless Rust was literally the only option. Thankfully it's never the only option, now or in the future.

      1 reply →

  • All three have very similar syntax when compared even to something like Python or Ruby, let alone ML or Haskell. Seems like a spurious complaint.

    • I mean, Rust is quite a different category than C or Go, if this is the 3 languages you reference.

      Rust has plenty of syntax coming straight from ML (okay, not straight, probably through OCaML)

      Pattern matching, destructuring, expressions everywhere, etc are stuff that C/Go never even heard about.

  • I don’t disagree, that’s part of why I like Swift so much. Rust looks very C++ to me.

    But if I was working in C++ and had a choice of C++ or Rust, I’d go Rust based on this.

  • Go is such a great language. If your code base doesn't mind garbage collection and doesn't depend on some external library, everyone should really look at go. Great multithreading, memory safe, great error handling, and a familiar syntax for people coming from C++/Java/etc.

    • > great error handling

      Go get this completely wrong! It use a tuple rather than an enum for potential errors. This means you can forget to check errors and just use the invalid (nil?) return value from the function.

      On the other hand, rust uses the Either enum to force you to handle the error. Alternatively you can use the ? operator to pass it to the calling function, which is reflected in the enclosing function's type.

      4 replies →

    • How is Go memory safe? Memory safety does not mean "leaking memory".

      It's absolutely possible to compute wrong pointer offsets. It's absolutely possible to dereference nil. It's absolutely possible to bork ownership and have multiple thread trample a struct. It's absolutely possible to reinterpret memory the wrong way.

      I do agree that UAF is not possible (in most cases) due to the GC. That array indexing out of bounds is not possible. But it is by no means "memory safe" to the level Rust is.

      6 replies →

    • Zig in spirit is essentially Go without GC. If GC is not reasonable for your usecase Zig seems like an awesome choice. Unfortunately it's probably about 5 to 10 years out from being stable enough for most people being able to write serious applications in it though (notable exceptions being Bun and Ghostty, but they have solid effort behind them keeping them up to date with Zig).

      2 replies →

    • > If your code base doesn't mind garbage collection and doesn't depend on some external library, everyone should really look at go

      I mean, at that point pretty much every language would be a decent choice.

    • Go has some of the worst error handling I've ever seen, even worse than most exception implementations IMO, and the type system is stupid enough that it's still very easy to write bugs. Go is only surface-level memory safe, you can definitely segfault in Go. And I mean real segfault, not nullptr dereference.

Cargo is absolutely awful. It might be better than cmake, but it still the worst part about Rust. It’s completely opaque, and intermixes a huge pile of different functionality.

Distributing Rust software is the pain that it is mostly because of how Cargo works. It’s pretty much impossible to sanely distribute something that isn’t a headache for downstream to consume.

  • > Cargo is absolutely awful. It might be better than cmake, but it still the worst part about Rust. It’s completely opaque, and intermixes a huge pile of different functionality.

    "Absolutely awful" strikes me as wild hyperbole -- you also meant it this way as well, right? What toolchains are not absolutely awful in your mind?

    Cargo isn't perfect by any stretch of the imagination -- there are a few common complaints that people have and a bunch of sharp edges (most of which have a github issue that has been open for years), but... "absolutely awful" has to be hyperbole.

  • Can you expand on your reasoning? Because the opposite seems to be true when it comes to projects like uv. People love the single-file executable -- easy to just compile that for a platform and have your users download it. It seems like the uv project is having a good time with that model, so I think they show it's not "impossible". Maybe they're doing something different I'm not aware of? Or maybe your use case is different, so what's impossible about your situation?

  • That sounds a lot like the issues some Linux distros are running into, where they expect to be able to ship one single blessed pre-compiled version of every library, and have each app load it dynamically at runtime.

    But that's just not how Rust works: it's trying to fit a square peg in a round hole, and it isn't Cargo's fault that you have trouble with it.

  • Can you say more?

    I’ve found it a joy to use compared to CMake and friends. How does it make it harder to consume something downstream? Seems easy enough to me - just share the source crate.

    Are you trying to distribute pre compiled code or something like that? I can see how that would be harder - cargo doesn’t really support that use case.

    How would you improve cargo?

    • > just share the source crate

      That’s a nice concrete example of something that sounds simple but is a nightmare.

      Let’s be clear: the goal is to distribute a tarball which the receiver can build. Crates won’t be packaged in the target host (that’s part of Rust’s design), so we don’t have any choice but to include them too.

      But there’s no simple way of gathering all of these. “cargo vendor” fetches all transitive dependencies for all platforms. So if any dependency supports windows, you end up with 400MB(!) of windows-only dependencies, even if your project doesn’t target windows. This makes “cargo target” useless.

      There’s “cargo-vendor-filtered”, a huge hack around this bug, but it’s also broke in subtle ways.

      In the end, if you want to distribute a tarball which a downstream can build, you can’t. Cargo works online only.

      Like I said: cargo is too opaque. There’s no command to generate a list of files that it would download for a build. There’s no command to fetch all “real” dependencies. It too opaque an monolithic, doing everything in one indivisible way. This is a great experience for the developer, but awful for anyone else.

      1 reply →

  • Uuuh how so?

    Cargo is a blessing for any source-available project. All bundled up, a `cargo build` away. Because don't you dare say CMake or autotools are better, that's just the stockholm syndrome kicking in because you're familiar with it.

    Seriously, how a CMakeLists.txt can even be compared to a Cargo.toml file? One is imperative full of arcane conditions everywhere filled with boilerplate, while Cargo.toml is a declarative manifest of the package?

    Though there is one very sore point when distributing software, and that is for distribution package maintainers, because the whole ecosystem has been built around the C model and dynamic linking. That is not even the fault of cargo, since Rust's ABI is not stable thus dynamic linking would not work most of the time. Another thorn is generic stuff, which needs to be monomorphized, and as such don't work with dynamic linking (without Box<dyn>); C++ actually has the same issue and is why there are so many "header only" libraries for it.

I dislike Rust, but I would definitely prefer it over the "Android Studio Java / Kotlin thing", for sure.