News for hackers. Stuff that matters.
Re:Was Rust Worth It? by lumost on Thursday October 26, 2023 @01:01AM (#38021782)
I tried to get into rust for many years, I'm now in a C/CPP job (after Java/Python/Ruby and other gigs). What I've come to understand is that Rust's lifetime model is very difficult to work with whenever you have a cyclic reference. In C/CPP the same holds, but you deal with it through clever coding - or ignoring the problem and cleaning up memory later. Java, and other GC'd languages just work for these structures.

While the Rust devs believe such cyclic references are rare - I think this speaks mostly to the problem domain they are focused on. Relational models are everywhere in Apps, they are often common in complex systems software like databases, and they are fairly rare in firmware/drivers/system code code.

There are a few patterns for dealing with cyclic references, but they all end up requiring either unsafe or a main "owner" object which you clean up occassionally (effectively arena allocation). Having now worked in C/CPP - the idea of having unsafe blocks sprinkled around the code doesn't bother me, and many C/CPP components have some form of arena allocation built-in. I just wish Rust learning resources would be more upfront about this.

Re:Was Rust Worth It? by lifthrasiir on Thursday October 26, 2023 @01:36AM (#38022005)
> Relational models are everywhere in Apps, they are often common in complex systems software like databases, and they are fairly rare in firmware/drivers/system code code.

It's not like that you can't write relational models in the safe Rust. The only forbidden thing is a reference pointing arbitrary memory, which is typically worked around via indices and often more performant in that way. It is much rarer to find applications that need an absolutely random pointer that can't be hidden in abstractions in my opinion.

Re:Was Rust Worth It? by goku12 on Thursday October 26, 2023 @01:15AM (#38021859)
> I just wish Rust learning resources would be more upfront about this.

While beginner resources don't dwell too much upon cyclic references, they don't consider unsafe blocks as unusual. All the material I've seen say that there are certain domains where Rust's compile-time safety model simply won't work. What Rust allows you to do instead, is to limit the scope of unsafe blocks. However, the beginner material often won't give you too much details on how to analyze and decide on these compromises.

Anyway, compile-time safety checks (using borrow checker) and manual safety checks (using unsafe) aren't the only way to deal with safety. Cyclic references can be dealt with runtime safety checks too - like Rc and Weak.

Re:Was Rust Worth It? by mtsr on Thursday October 26, 2023 @02:50AM (#38022516)
> Cyclic references can be dealt with runtime safety checks too - like Rc and Weak.

Indeed. Starting out with code sprinkled with Rc, Weak, RefCell, etc is perfectly fine and performance will probably not be worse than in any other safe languages. And if you do this, Rust is pretty close to those languages in ease of use for what are otherwise complex topics in Rust.

A good reference for different approaches is Learn Rust With Entirely Too Many Linked Lists https://rust-unofficial.github.io/too-many-lists/

Re:Was Rust Worth It? by pncnmnp on Thursday October 26, 2023 @03:33AM (#38022803)
Also, take a look at GhostCell (https://plv.mpi-sws.org/rustbelt/ghostcell/ and https://www.youtube.com/watch?v=jIbubw86p0M). If anyone's used this in a project or production environment, I'd love to hear your firsthand experiences and insights.
Re:Was Rust Worth It? by pjmlp on Thursday October 26, 2023 @04:45AM (#38023248)
Except in those other languages the compiler types .clone() for me.
Re:Was Rust Worth It? by chalsprhebaodu on Thursday October 26, 2023 @07:14AM (#38024076)
Sometimes the compiler types clone for you even you don’t actually want it to.
Re:Was Rust Worth It? by pjmlp on Thursday October 26, 2023 @08:19AM (#38024549)
It is easier to tell it, "don't do it this time" than all the time.

It is no accident that while Val/Hylo, Chapel and Swift have taken inspiration from Rust, they have decided to not inflict the affine types directly into the language users, rather let the compiler do part of the work itself.

Re:Was Rust Worth It? by lumost on Friday October 27, 2023 @04:34PM (#38043549)
You still need a main owner in those patterns, that owner must be part of a DAG of owners - you cannot have cyclic ownership.
Re:Was Rust Worth It? by mjevans on Thursday October 26, 2023 @01:54AM (#38022119)
What's a frequently encountered case for such cyclic loops? Without details I'm drawn to trying to break the cycle, either by promoting the shared state to a container object for the set, or by breaking it out into it's own object that multiple things can point at.
Re:Was Rust Worth It? by rurban on Thursday October 26, 2023 @02:12AM (#38022267)
a parent field.

a doubly linked list

Re:Was Rust Worth It? by littlestymaar on Thursday October 26, 2023 @03:55AM (#38022945)
Doubly-linked list is something you have almost no reason to ever write.

Parent field is something where you have a clear hierarchy (it's not really “cyclic”, so it's the perfect use-case for weak references).

When coming from a managed-memory language, this obviously requires some conceptual effort to understand why this is a problem at all and how to deal with it, but when compared to C or C++, the situation is much better in Rust.

Re:Was Rust Worth It? by jacobgorm on Thursday October 26, 2023 @04:54AM (#38023302)
Also, a parent field is something you should be able to infer, e.g, keep a stack of parents as you traverse down a search tree following the child pointers, instead of storing parent pointers in the tree nodes.
Re:Was Rust Worth It? by akoboldfrying on Thursday October 26, 2023 @05:16AM (#38023428)
That's assuming you traverse the tree down from the root each time. Often you do, but there are cases where you don't -- e.g., if your goal is to determine the lowest common ancestor of two given nodes.
Re:Was Rust Worth It? by tialaramex on Thursday October 26, 2023 @04:46AM (#38023257)
Your parent said "frequently encountered" and while it's probably true that doubly linked lists may be "frequently encountered" in some people's code they're usually a bad idea and "don't use a list here" is often the right fix, not "conjure a way to make that safe in Rust".

It's very noticeable how often people who "need" a linked list actually only wanted a queue (thus Rust's VecDeque) or even a growable array (ie Vec).

Aria has a long list of excuses people offer for their linked lists, as well as her discussion of the time before Rust 1.0 when she sent lots of Rust's standard library collections to that farm up-state but wasn't able to send LinkedList.

https://rust-unofficial.github.io/too-many-lists/

Re:Was Rust Worth It? by solomonb on Thursday October 26, 2023 @02:06AM (#38022202)
ASTs
Re:Was Rust Worth It? by mjevans on Thursday October 26, 2023 @02:41AM (#38022459)
An Abstract Syntax Tree / or Double-Linked List both qualify, but they're also a lower level implementation detail than I'd expect to frequently interact with in a reference safety focused language.

I've still been meaning to write something in / learn Rust's ways of thinking; is there not an intended replacement for these data structures? Or do they expect it all to go under Unsafe?

Re:Was Rust Worth It? by littlestymaar on Thursday October 26, 2023 @04:05AM (#38022999)
> is there not an intended replacement for these data structures? Or do they expect it all to go under Unsafe?

For linked-lists, there's one in std and the majority of people should never have to write their own as it's error prone and requires unsafe.

For graph use-case then you can either use ECS, arena, ref counting or unsafe, but you're probably better off using/developing a dedicated crate that optimizes it and abstract it away behind an easy to use (and safe) interface.

Re:Was Rust Worth It? by lumost on Friday October 27, 2023 @04:45PM (#38043688)
The one in std uses unsafe. My main concern with learning rust is that you can spend ages trying to learn “the right way” of doing things in rust, when the right way really is to use unsafe.
Re:Was Rust Worth It? by littlestymaar on Saturday October 28, 2023 @02:45PM (#38052335)
No, the right way is to use unsafe primitives that have been tested, audited or even formally proven (like the ones in std).

Sometimes such a primitive doesn't exist and you should use unsafe yourself, but then you're the one supposed to make sure that your code is in fact sound. If you keep unsafe for small portions of the code you can reason about and extensively test so Miri gives you a good level of confidence, then it's fine to use unsafe. But it's the more expensive option, not the default.

Re:Was Rust Worth It? by lifthrasiir on Thursday October 26, 2023 @02:14AM (#38022275)
ASTs are one of "nicely behaving" data structures. It is like a archetype of abstract data types pervasive in functional programming languages.
Re:Was Rust Worth It? by SkiFire13 on Thursday October 26, 2023 @03:26AM (#38022747)
An abstract syntax tree can't have cycles by definition.
Re:Was Rust Worth It? by foldr on Thursday October 26, 2023 @03:52AM (#38022925)
Technically true, but sometimes you want parent pointers. You then have a more general graph in the underlying representation, but it still represents a tree structure.
Re:Was Rust Worth It? by lumost on Friday October 27, 2023 @04:43PM (#38043665)
Same shows up in Postgres Query* struct for SQL. Copying memory between parser, planner, execution would be too expensive in large queries - so instead you have an arena allocated representation.
Re:Was Rust Worth It? by mordae on Thursday October 26, 2023 @05:27AM (#38023488)
You usually solve this by using a traversal helper that keeps the stack and next/prev for you without storing them inside the AST explicitly.
Re:Was Rust Worth It? by oconnor663 on Thursday October 26, 2023 @09:48AM (#38025483)
I think a game is a good example, or anything that's kind of like a game in that it's modeling a world that's changing over time. Objects come and go, and they "target" each other or "require" each other or whatever sort of relationships the program wants to express. Those relationships end up forming a graph that might contain cycles.

I just put up a blog post about this actually :) https://jacko.io/object_soup.html

> promoting the shared state to a container object for the set

Yeah I think that's a good way to describe these "ECS-ish" patterns.

Re:Was Rust Worth It? by worik on Thursday October 26, 2023 @05:38AM (#38023555)
> While the Rust devs believe such cyclic references are rare -

They are.

I have not had to use cyclic references ever, except once doing experiments with fully connected graphs, that was very unusual

If you're doing a lot cyclic references Rust is not the right choice. Horses for courses

But are you sure you're using the best algorithm?

Re:Was Rust Worth It? by jcelerier on Thursday October 26, 2023 @08:35AM (#38024697)
Maybe for you it's unusual - in my previous work all the apps contained graphs, and I just joined a company where almost all the apps also contain graphs
Re:Was Rust Worth It? by underdeserver on Thursday October 26, 2023 @09:12AM (#38025058)
I don't write Rust, but I never understood why graphs meant you need circular references.

Doesn't it just come down to the question of who owns the node?

If it's a tree, and parents are never removed before children, just make the child owned by the parent and keep a weak reference to the parent.

If it's a general graph, and vertices can exist or not exist regardless of edges, keep a list of them independent of the edges, and keep weak references in the edges.

If it's a graph where a one or a few roots exist, and nodes exist as long as there's a path from a root node to them, that sounds like a classic use case for Rc<>.

Is there a common use case I'm missing?

Re:Was Rust Worth It? by lumost on Friday October 27, 2023 @04:38PM (#38043610)
Things get tricky when you have a valid triangular relationship amongst equal objects. This comes up far more often than you’d expect.
Re:Was Rust Worth It? by underdeserver on Sunday October 29, 2023 @12:33AM (#38055823)
Can you give an example?
Re:Was Rust Worth It? by zabzonk on Thursday October 26, 2023 @05:45AM (#38023581)
to be a bit pedantic, i assume the language you a referring to as CPP is actualy C++? cpp to me means the c (and c++) preprocessor.
Re:Was Rust Worth It? by oconnor663 on Thursday October 26, 2023 @09:23AM (#38025182)
Oh I just put up a blog post about this on Monday :)

https://jacko.io/object_soup.html

Agreed that I wish more beginner Rust books had a section about this. The pattern is quite simple, but it's hard for beginners who get stuck to realize that they need it.

Re:Was Rust Worth It? by strokirk on Saturday October 28, 2023 @07:38AM (#38049028)
I would have needed this when I started learning Rust! All my early programs were object soups.