Comment by mk89

6 months ago

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.

    • > 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.

      I find rust generally more terse than both C and - especially Go, to which rust was compared upthread. Writing out lifetimes explicitly can be confusing. But I don't think it adds that much syntactic noise. Maybe 1/20 functions in my code have explicit lifetimes. That will confuse beginners, but I don't think its too bad once you're used to them.

      > And, dealing with pointers ultimately introduces multiple layers of concepts that you don't necessarily run into with C++/Go/Java.

      This is my #1 complaint about rust's syntax. If you ever need to interact with raw pointers within unsafe blocks, I feel like the language really fights you. It seems so strange, too - since unsafe blocks are exactly the place where it matters the most that my code is easy to read. Improving the syntax around pointers (for example by adding C's -> operator) would make unsafe blocks clearer.

  • 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.

    • Can you give some examples? Its hard to agree or disagree if you're not going to make any substantive claims.

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.

    • Pet peeves nitpick: it's not even a tuple. Go doesn't have tuples. It just has special-cased "multiple return values", which means that it's often impossible to just stuff the return of a function call (error value and all) into any data structure to aggregate them. You just can't do without first defining a struct since tuples don't exist in Go.

    • Yep Rust approach won. Pretty much every new language is adopting Result style errors and it's been adapted to plenty of existing languages.

      It's a product of functional programming, and for me I can't see how you would ever want to handle errors outside of the functional programming railway-oriented style. For me it's just superior.

      2 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.

    • > It's absolutely possible to bork ownership and have multiple thread trample a struct.

      This is specifically the one place where go is not memory safe IMO.

      > It's absolutely possible to compute wrong pointer offsets.

      In Go? Without the `unsafe` package (at which point you are explicitly opting out)? How? There's no pointer offset in the first place.

      > It's absolutely possible to dereference nil.

      Yeah, but that's safe defined behavior in go equivalent to "unwrap"ing a None option in rust. It reliably crashes. It's not like C where it's undefined behavior and you might crash of you might just corrupt random memory or have the optimizer make your code do something even stranger.

      It's (really the lack of non-nil types) is one of many reasons why go doesn't produce as reliable software as rust, but it's not a memory safety issue.

      > It's absolutely possible to reinterpret memory the wrong way.

      Again, without the unsafe package? How?

      3 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).

  • > 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.