Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The doubly linked list thing strikes me as more of an illustration of cultural differences between C programmers an the rest of the world than as a straightforward criticism of Rust.

I've no doubt that doubly linked lists are an awkward hassle to implement in Rust. But the same is true in functional languages, and you never hear people criticizing, e.g., Haskell over this. I have a couple guesses as to why that is, but I'm guessing the main one is that Rust being touted as a C replacement results in people assuming that Rust should be amenable to the same kind of (for lack of a better way to put it) hyper-imperative approach to problem solving that C basically forces upon people.

But I'm also pretty sure that I've never, in my 30 years of programming, used a doubly linked list in anger in a language that wasn't C. (Maybe Pascal?) I have never used Rust in anger, either, but, based on my little bit of dabbling, it seems like yet another language where I would be likely to choose any number of different data structures first. I certainly wouldn't be implementing my own in any case. These days, implementing doubly linked lists from scratch seems to be very nearly the sole province of C programmers and undergraduates.



It's not just doubly linked lists. They're just a basic example of borrow checking not being able to handle a lot of easy patterns that are perfectly safe in other languages.


The easy pattern of graph structures is handled by the easy implementation of adjacency lists, which is how you should have been implementing it in other languages too. The specific incompatibility is with the naïve hand-implementations of these structures; the specific thing Rust does not optimize for is toy code.


You know nothing of what I'm programming. You don't know when, whether, or how my program accesses or deletes data. You don't know what domain I'm in, whether I'm on a team, or what our priorities must be.

And yet, you proclaim that your approach is how I should always do it in any language, in any situation.

It strikes me as particularly convenient, seeing as that's the only approach that the borrow checker can reason about.

To make it more concrete: if we apply your solution everywhere we run into this problem with the borrow checker, it can flatten a lot of our program's (non-temporary) state into basically relational tables. Sometimes that's okay, but for a lot of situations it can be bad for encapsulation, velocity, and modularity.


No need to take it personal. I don't think the "you" OP used referred to you specifically.


I agree with the sibling commenter that the parent poster was likely using the impersonal you. It is true that we don't know anything about you. You haven't volunteered any specifics, so we're kind of forced to guess if we want to try and respond in a productive manner.

To that end, I think that they chose a very good example. Abstractly, doubly linked lists are a special case of undirected graphs. So pointing out that a naive graph implementation is generally sup-optimal, and that usually one can more effectively model them using different data structures that Rust (and functional languages, and databases, and files, etc.) can handle just fine, neatly addresses problems that one might solve using a doubly linked list, as well as a whole host of other cases, in a single stroke.


Fair, but, if so, could we focus on one of those instead?

I'd be especially interested to see an example that's perfectly safe in C or C++, and for which there's no better way of doing the data modeling in Rust. Using the kinds of data patterns that have long been used to avoid circular references in functional programming languages, for example. Because we want to avoid getting too caught up in examples of things that should be hard in Rust because Rust is designed to favor different ways of doing things.

Or, to put it cutely, I'd want to be cautious about doing the equivalent of criticizing a Toyota for having a terrible glide slope.


Perfectly safe at the expense of a garbage collector. You can still do pointer soup and int handle based lists as you can do in any other low-level language with the same caveats. Rust is punching up from the manual memory management, zero-cost abstraction plane and competing with the garbage collected langs. It's still at it's core a tool for writing low level code.


GP was confused about why the doubly linked list case was so important, so I enlightened, it's an example of an entire class of the borrow checker's problems.

Your response isn't really relevant in that context, and instead escalates to a much larger debate, so best I not engage. Appreciate the thought though =)


These patterns are not "easy" at all - for one thing, they're non-compositional and anti-modular. They're exactly the kind of thing `unsafe {}` was intended for - though it would be nice if Rust came with a way of writing proofs of safety for these things, and this is a field of active research.




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: