Live data from Hacker News

The borrowchecker is what I like the least about Rust

viralinstruction.com

151–160 of 459 posts

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

#151
There are some artificial limitations, but I love the upside: I don't need defensive programming!

When my function gets an exclusive reference to an object, I know for sure that it won't be touched by the caller while I use it, but I can still mutate it freely. I never need to make deep copies of inputs defensively just in case the caller tries to keep a reference to somewhere in the object they've passed to my function.

And conversely, as a user of libraries, I can look at an API of any function and know whether it will only temporarily look at its arguments (and I can then modify or destroy them without consequences), or whether it keeps them, or whether they're shared between the caller and the callee.

All of this is especially important in multi-threaded code where a function holding on to a reference for too long, or mutating something unexpectedly, can cause painful-to-debug bugs. Once you know the limitations of the borrow checker, and how to work with or around them, it's not that hard. Dealing with a picky compiler is IMHO still preferable to dealing with mysterious bugs from unexpectedly-mutated state.

In a way, borrow checker also makes interfaces simpler. The rules may be restrictive, but the same rules apply to everything everywhere. I can learn them once, and then know what to expect from every API using references. There are no exceptions in libraries that try to be clever. There are no exceptions for single-threaded programs. There are no exceptions for DLLs. There are no exceptions for programs built with -fpointers-go-sideways. It may be tricky like a game of chess, but I only need to consider the rules of the game, and not odd stuff like whether my opponent glued pieces to the chessboard.

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

#153
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…

> hundreds of millions of dollar

Yes.

> in advertising

No, in hiring 500 compiler and tool developers, developing and supporting libraries, optimizing it for niche use cases.

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

#154
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…

> it is nicer to write in those other languages

I think this is a matter of preference. Nowadays I cannot stand environments like Java (or especially Kotlin). "Tricky memory errors" is in my opinion nicer than a borrow-checker refusing sound code. I guess I really hate 'magic'...

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

#155

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…

[flagged]

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

#156

Earlier quoted context omitted.

Maybe I’m wrong, but I only really know of Jane Street for OCaml, meanwhile FAANG all has at least some rust code. Also I would argue the rust compiler started as a hobby project

Facebook Messenger's backend was/is OCaml... React was originally written in SML, then OCaml, then whatever it is now. And a bunch of places use it for various things. https://ocaml.org/industrial-users

React was never written in SML or Ocaml. It was originally called FaxJS, and the source code is published online.

A version of React was built to run in ReasonML, which is a flavor of Ocaml for the web, but Reason didn't even exist before React was fairly well established.

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

#157

Earlier quoted context omitted.

Everytime I try to use bumpalo I get frustrated, give up, and fallback to RAII allocation bullshit. My last attempt is I had a text file with a custom DSL. Pretend it’s JSON. I was parsing this into a collection of nodes. I wanted to dump the file into an arena. And then have all the nodes have &str living in and tied to the arena. I wanted zero unnecessary copies. This is trivially safe code. I’m sure it’s possible.…

To make sure I understand correctly: did you want to read a `String` and have lots of references to slices within the same string without having to deal with lifetimes? If so, would another variant of `Rc ` which supports substrings that also update the same reference count have worked for you? Looking through crates.io, I see multiple libraries that seem to offer this functionality: [1]: https://crates.io/crates/arc…

It’s deeper than that.

Let’s pretend I was in C. I would allocate one big flat segment of memory. I’d read the “JSON” text file into this block. Then I’d build an AST of nodes. Each node would be appended into the arena. Object nodes would container a list of pointers to child nodes.

Once I built the AST of nested nodes of varying type I would treat it as constant. I’d use it for a few purposes. And then at some point I would free the chunk of memory in one go.

In C this is trivial. No string copies. No duplicated data. Just a bunch of dirty unsafe pointers. Writing this “safely” is very easy.

In Rust this is… maybe possible. But brutally difficult. I’m pretty good at Rust. I gave up. I don’t recall what exact what wall I hit.

I’m not saying it can’t be done. But I am saying it’s really hard and really gross. It’s radically easier to allocate lots of little Strings and Vecs and Box each nested value. And then free them all one-by-one.

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

#158

This reminds me of something that was popular in some bioinformatics circles years ago. People claimed that Java was faster than C++. To "prove" that, they wrote reasonably efficient Java code for some task, and then rewrote it in C++. Using std::shared_ptr extensively to get something resembling garbage collection. No wonder the real Java code was faster than the Java code written in C++. I've been writing C++ for a…

If using indices is going to be your answer, then it seems to me you should at least contend with the OP's argument that this approach violates the very reason the borrowchecker was introduced in the first place. From the post: "The Rust community's whole thing is commitment to compiler-enforced correctness, and they built the borrowchecker on the premise that humans can't be trusted to handle references manually. Wh…

>OP's argument that this approach violates the very reason the borrowchecker was introduced in the first place.

No it doesn't. I just don't think author understands the pitfalls of implementing something like a graph structure in a memory unsafe language. The author doesn't write C so I don't believe he has struggled with the pain of chasing a dangling pointer with valgrind.

There are plenty of libraries in C that eventually decided to use indexes instead of juggling pointers around because it's much harder to eventually introduce a use-after-free when dereferencing nodes this way.

Entity component systems were invented in 1998 which essentially implement this pattern. I don't find it ironic that the Rust compiler herds people towards a safe design that has been rediscovered again and again.

The borrow checker was introduced to statically verify memory safety. Using indices into graphs has been a memory safe option in languages like C for decades. I find his argument as valid as if someone said "I can't use goto? you expect me to manually run my cleanup code before I return?" Just because I took away your goto to make control flow easier it doesn't make it "ironic" if certain legitimate uses of goto are harder. Surely you wouldn't accept his argument for someone arguing for the return of goto in mainstream languages?

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

#159

Earlier quoted context omitted.

If using indices is going to be your answer, then it seems to me you should at least contend with the OP's argument that this approach violates the very reason the borrowchecker was introduced in the first place. From the post: "The Rust community's whole thing is commitment to compiler-enforced correctness, and they built the borrowchecker on the premise that humans can't be trusted to handle references manually. Wh…

I think this is like unsafe - most of your code won’t have it, so you get the benefits of borrow checker (memory safety and race freedom) elsewhere.

An important saving grace that `unsafe` has is that it's local and clearly demarcated. If a core data structure of your program can be compared to `unsafe` and has to be manually managed for correctness, it's very valid to ask whether the hoops Rust makes you jump through are actually gaining you anything.

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

#160

This reminds me of something that was popular in some bioinformatics circles years ago. People claimed that Java was faster than C++. To "prove" that, they wrote reasonably efficient Java code for some task, and then rewrote it in C++. Using std::shared_ptr extensively to get something resembling garbage collection. No wonder the real Java code was faster than the Java code written in C++. I've been writing C++ for a…

If using indices is going to be your answer, then it seems to me you should at least contend with the OP's argument that this approach violates the very reason the borrowchecker was introduced in the first place. From the post: "The Rust community's whole thing is commitment to compiler-enforced correctness, and they built the borrowchecker on the premise that humans can't be trusted to handle references manually. Wh…

The OP's argument is bunk. It's been said many times too over the years. The fact is that the index approach does not give up everything. The obvious thing it doesn't give up is safety. It's true you can still get bugs via out of bounds accesses, but it won't result in undefined behavior. You get a panic instead.

This is how the regex crate works internally and uses almost no `unsafe`.

Post reply on HN