Hacker News new | ask | show | jobs
by Imustaskforhelp 605 days ago
In my opinion , I like golang's way better because then you have to be thoughtful about your dependencies and it also prevents any drama (like rust foundation cargo drama) (ahem) (if you are having a language that is so polarizing , it would be hard to find a job in that )

I truly like rust as a performance language but I would rather like real tangible results (admittedly slow is okay) than imagination within the rust / performance land.

I don't want to learn rust to feel like I am doing something "good" / "learning" where I can learn golang at a way way faster rate and do the stuff that I like for which I am learning programming.

Also just because you haven't learned rust doesn't make you inferior to anybody.

You should learn because you want to think differently , try different things. Not for performance.

Performance is fickle minded.

Like I was seeing a native benchmark of rust and zig (rust won) and then I was seeing benchmark of deno and bun (bun won) (bun is written in zig and deno in bun)

The reason I suppose is that deno doesn't use actix and non actix servers are rather slower than even zig.

It's weird .

1 comments

There are some influential fair comparisons of compiled languages, but for the most part my feeling is that people are moving from an extremely high level language like Python or JS, and then going to Rust to get performance, when any single compiled language would be fine, and for 90% of them, Go would have been the right choice (on backend or web-enabled systems apps), there was just a hurdle to get to most other compiled languages.

It's just Rust is somehow more accessible to them? Maybe it's that pointers and memory just was an inaccessible / overburdensom transition?

Rust is the only mainstream language with an ergonomic modern type system and features like exhaustive matching on sum types (AFAIK... maybe I'm forgetting one). Yes things like OCaml and Haskell exist but they are much less mainstream than Rust. I think that's a big part of the appeal.

In Go instead of having a value that can be one of two different types, you have to have two values one of which you set to the zero value. It feels prehistoric.

That strikes me as an incredibly niche (and probably transient) strength! But I will remember that.
It's not niche at all; it's extremely common to need this. Maybe I'm not explaining it well. For example, an idiomatic pattern in Go is to return two values, one of which is an error:

  func f() (SomeType, error) {
          // ...
  }
In Rust you would return one value:

  fn f() -> anyhow::Result<SomeType> {
      // ...
  }
In Go (and similar languages like C) nothing enforces that you actually set exactly one value, and nothing enforces that you actually handle the values that are returned.

It's even worse if you need to add a variant, because then it's easy to make a mistake and not update some site that consumes it.

To be fair even Java solves this problem with checked exceptions. It forces you to handle them or pass them on. It's really just C++ and C# that have a bit of wild west error handling.
My point has nothing specifically to do with error handling, that was just the first example that came to mind.
> Rust is the only mainstream language with an ergonomic modern type system and features like exhaustive matching on sum types (...)

This reads like a parody of Rust's fandom.

Sorry, what other mainstream language has this feature? I supposed TypeScript does, but we were talking about compiled languages.
Swift does apparently, here's an example from ChatGPT

    enum Animal {
        case dog(name: String)
        case cat(name: String)
        case bird

        func sound() {
            switch self {
            case .dog(let name):
                print("\(name) says Woof!")
            case .cat(let name):
                print("\(name) says Meow!")
            case .bird:
                print("Tweet!")
            }
        }
    }
and another with nesting

    enum Thing {
        case first(x: Int)
        case second
    }

    enum Outer {
        case ok(Thing?)
    }

    let value: Outer = .ok(.some(.first(x: 42)))

    switch value {
    case .ok(.some(.first(let x))):
        print("Matched with x = \(x)")
    case .ok(.some(.second)):
        print("Matched .second")
    case .ok(.none):
        print("Matched .none")
    }
Cool, and Swift is indeed a mainstream language, so fair enough that my original claim wasn't quite correct.

I still think it's a meaningful reason for Rust's popularity, though, given that Swift isn't used much outside of the Apple ecosystem.

Scala, Kotlin and even modern Java.
> It's just Rust is somehow more accessible to them?

Going to lower level languages can be scary. What is 'fighting the borrow-checker' for some, may be 'guard rails' for others.

Not sure how much it weighs on the balance in those types of decisions. But Rust has safe concurrency. That's probably quite a big boost of web server quality if anything else.
Go's concurrency is unsafe? Rust's concurrency is automatically safe?

I am not saying you're wrong, I just don't find it any better than C++ concurrent code, you just have many different lock types that correspond to the borrow-checker's expectations, vs C++'s primitives / lock types.

Channels are nicer, but that's doable easily in C++ and native to Go.

(Un)safe is a bit of an overloaded term but Rust's concurrency model is safe in the sense that it statically guarantees that you won't have data races. Trying to mutate the same memory location concurrently is a compile-time error. Neither C++ nor Golang prevent you from doing this. Aside from that
With the caveat that those data races are related to in-process memory being accessed by threads.

Which is quite good, but leaves out shared memory with other processes, or threads having data races with external resources, while corner cases they are quite common in distributed computing scenarios.

You've been really obsessed by this for a long time and I'd be interested to understand if there's some specific trigger, something weird you're doing where this seems to you like it's a data race, because I have never seen anywhere that I was like "oh, I guess this is a data race" when there's unsynchronized access across process boundaries.
> Go's concurrency is unsafe? Rust's concurrency is automatically safe?

Yes and yes...

Rust statically enforces that you don't have data races, i.e. it's not possible in Rust (without unsafe hacks) to forget to guard access to something with a mutex. In every other language this is enforced with code comments and programmer memory.

As long as that something is in the process's own memory.
Correct, rust doesn’t magically prevent all bugs. It just makes a large class of bugs harder to write.