Live data from Hacker News

The borrowchecker is what I like the least about Rust

viralinstruction.com

181–190 of 459 posts

Re: The borrowchecker is what I like the least about Rust

#181
post #57

Earlier quoted context omitted.

This is also somewhat backed up by the fact that OCaml (to my understanding) is basically GC Rust without a borrow checker, and yet it’s basically a hobby language.

I think there are two other big differences that also helped Rust become popular: * Rust has a C++-flavored syntax, but OCaml has a relatively alien ML-flavored syntax. * Rust has the backing of Mozilla, but I don't think OCaml had comparable industry backing. (Jane Street, maybe?)

> rust has a C++-flavored syntax

I do not at all agree with this. Rust is by far the most complex language in terms of syntax that has ever become popular enough to compare it to anything.

Re: The borrowchecker is what I like the least about Rust

#182
post #63

What's the alternative though? If you're fine with garbage collection, just use garbage collection. If you're _not_ fine with garbage collection (because you want deterministic performance, or you have resources that aren't just memory) then Rust's borrow checker seems like the best thing going.

You can use Zig, a faster, safer C with best-in-class metaprogramming for a systems-level language. It doesn't guarantee safety to the same extent as Rust but gets you 80% of the benefit with 20% of the pain.

Re: The borrowchecker is what I like the least about Rust

#183
> My examples code above may not be persuasive to experienced Rustaceans. They might argue that the snippets don't show there is any real ergonomic problem, because the solutions to make the snippets compile are completely trivial. In the last example, I could just derive Clone + Copy for Id.

No, you could use destructuring. This doesn't work for all cases but it does for your examples without needing to derive copy or clone. Here's a more complex but also compelling example of the problem:

    struct Graph {
        nodes: BTreeMap,
    }

    struct Node {
         edges: Vec,
    }

    impl Graph {
        fn visit_mut(&mut self, visit: impl Fn(&mut Node, &mut Node)) {
            let mut visited = BTreeSet::new();
            let mut stack = vec![0];
            while let Some(id) = stack.pop() {
                if !visited.insert(id) { continue; }
                let curr = self.nodes.get_mut(&id);
                for id in source.edges.clone() {
                    let next = self.nodes.get_mut(&id);
                    visit(curr, next);
                    stack.push(id);
                }
            }
        }
    }
We're doing everything in the "Rust" way here. We're using IDs instead of pointers. We're cloning a vec even if it's a bit excessive. But the bigger problem is we actually _do_ need to have multiple mutable references to two values owned by a collection that we know don't transitively reference the collection. We need to wrap these in an RefCell or UnsafeCell and unsafe { } block to actually get mutable references to the underlying data to correctly implement visit_mut().

This is a problem that shows up all the time when using collections, which Rust encourages within the ecosystem.

Re: The borrowchecker is what I like the least about Rust

#184

Earlier quoted context omitted.

> If you go out of bounds, Rust will panic and tell you exactly where it panicked This arguement has a long history. It is a widely used pattern in rust. It is true that panics are memory safe, and there is nothing unsafe about having your own ref ids. However, I believe thats its both fair and widely acknowledged that in general this approach is prone to bugs that cause panics for exactly this reason, and thats bad.…

I wish Rust had syntax or a directive to make Rcs a bit less obtrusive.

This is being worked on: https://rust-lang.github.io/rust-project-goals/2025h1/ergono...

Re: The borrowchecker is what I like the least about Rust

#185

I don't use Rust much, but I agree with the thrust of the article. However, I do think that the borrowchecker is the only reason Rust actually caught on. In my opinion, it's really hard for a new language to succeed unless you can point to something and say "You literally can't do this in your language" Without something like that, I think it just would have been impossible for Rust to gain enough momentum, and also…

Agreed. As a comparison Golang was sold as "CSP like Erlang without the weird syntax" but people realized channels kind of suck and goroutines are not really a lot better than threads in other languages. The actual core of OTP was the supervisor tree but that's too complicated so Golang is basically just more concise Java. I don't think this is a bad thing but it's a funny consequence that to become mainstream you ha…

I can't substantiate your claim about Erlang or weird syntax, is that either a proper quote or some kind of paraphrasing because nothing remotely close to it comes up.

There are numerous interviews with Rob Pike about the design of Go from when Go was still being developed, and Erlang doesn't come up in anything that I can find other than this interview from 2010 where someone asks Rob Pike a question involving Erlang and Rob replies by saying he thinks the two languages have a different approach to are fairly different:

https://www.youtube.com/watch?v=3DtUzH3zoFo

It's at the 32 minute mark, but once again this is in response to someone asking a question.

Here are other interviews about Go, and once again in almost every interview I'd say Rob kind of insinuates he was motivated by a dislike of using C++ within Google to write highly parallel services, but not once is Erlang ever mentioned:

https://www.informit.com/articles/article.aspx?p=1623555

https://www.infoq.com/interviews/pike-google-go

https://go.dev/blog/waza-talk

Re: The borrowchecker is what I like the least about Rust

#186

> [The pain of the borrow checker is felt] when your existing project requires a small modification to ownership structure, and the borrowchecker then refuses to compile your code. Then, once you pull at the tiny loose fiber in your code's fabric, you find you have to unspool half your code before the borrowchecker is satisfied. Probably I just haven't been writing very "advanced" rust programs in the sense of doing…

I've mostly experienced it when moving from borrowing to ownership and vice versa. E.g. having a struct that takes ownership over its fields, and then moving it to a borrow with a lifetime.

It's not super common though, especially if the code is not in the hot path which means you can just keep things simple and clone.

Re: The borrowchecker is what I like the least about Rust

#187
post #92

Earlier quoted context omitted.

We do admit it needs work. The issues the author highlights can be annoying, a smarter borrow checker could maybe solve them. The point is the borrow checker has already gone beyond the point where the benefits outweigh those annoyances. It's like... Static typing. Obviously there are cases where you're like "I know the types are correct! Get out of my way compiler!" but static types are still vastly superior because…

> The issues the author highlights can be annoying, a smarter borrow checker could maybe solve them I don't think a smarter borrow checker could solve most of the issues the author raises. The author wants borrow checking to be an interprocedural analysis, but it isn't one by design. Everything the borrow checker knows about a function is in its signature.

Fixing the get_default example wouldn't require interprocedural analysis. (It requires Polonius, which, yeah, has taken a long time to ship.)

Re: The borrowchecker is what I like the least about Rust

#188
post #94

Earlier quoted context omitted.

This is also somewhat backed up by the fact that OCaml (to my understanding) is basically GC Rust without a borrow checker, and yet it’s basically a hobby language.

> and yet it’s basically a hobby language. The difference between academia languages such as ocaml or haskell and industry languages such as Java or C# is hundreds of millions of dollar in advertising. It's not limited to the academy: plenty of languages from other horizons failed, that weren't backed by companies with a vested interest in you using their language. You should probably not infer too much from a langua…

The main difference is the ecosystem. The Haskell community has always focused primarily on the computer science part, so the developer experience has mostly been neglected. They have been unable to attract a large enough hobbyist community to develop the libraries and tooling you'd take for granted with any other language, and no company is willing to pay for it out of pocket either. Even load-bearing libraries feel like a half-finished master's thesis, because that's usually what it is.

No amount of advertising is going to propel Haskell to a mainstream language. If it wants to succeed (and let's be honest, it probably doesn't), it's going to need an investment of millions of developer-hours in libraries and tooling. No matter how pretty and elegant the language may be, if you have to reinvent the wheel every time you go beyond "hello world" you're going to think twice before considering it for production code.

Re: The borrowchecker is what I like the least about Rust

#189
post #144

I choose a language that is as ergonomic as possible, but as performant as necessary. If e.g. Kotlin is fine, there is no way I will choose Rust. Many projects are written in Rust that would absolutely be fine in Go, Swift or a JVM language. And I don't understand: it is nicer to write in those other languages, why choose Rust? On the other hand, Rust is a lot nicer than C/C++, so I see it as a valid alternative ther…

I mostly agree with you, but ironically the article's own conclusion answers this: the language's general ethos is designed for correctness-oriented programming in the large, and this gives rise to lots of other features that garbage-collected languages could adopt but mostly don't. Like, it's way harder to avoid runtime panics in Go. (Swift does okay but people don't have faith that its custodians will do an adequate job of prioritizing the needs of developers using it for anything other than client-side apps on Apple platforms, and also it's slightly too low-level in that it doesn't have a tracing garbage collector either.)

Re: The borrowchecker is what I like the least about Rust

#190
post #70

One of his examples of a borrow checker excess: struct Id(u32); fn main() { let id = Id(5); let mut v = vec![id]; println!("{}", id.0); } isn't even legit in modern C++. That's just move semantics. When you move it, it's gone at the old name. He does point out two significant problems in Rust. When you need to change a program, re-doing the ownership plumbing can be quite time-consuming. Losing a few days on that is…

> isn't even legit in modern C++. That's just move semantics. When you move it, it's gone at the old name.

Exactly the opposite actually.

Rust has destructive move while modern C++ has nondestructive move.

So in Rust, an object is dead after you move out of it, and any further attempts to use it are a compiler diagnosed error. In contrast, a C++ object is remains alive after the move, and further use of it isn't forbidden by the language, although some or all uses might be forbidden by the specific user provided move function - you'll have to reference the documentation for that move function to find out.

This article explains the difference well: https://www.foonathan.net/2017/09/destructive-move/

Post reply on HN