Follow

Literally every pattern to work around Rust's borrow checker is just implementing an allocator yourself and then convincing the compiler that it's not actually an allocator

· · Web · 2 · 0 · 2

@hazel I feel like trying to work around the borrow checker is the wrong way to program in Rust

@justinfrank You'd think that, and yet it's the only way to do anything sane

@justinfrank Every single time a Rust developer says "Just index into it rather than passing around a reference", what they're actually doing is just reimplementing memory

@justinfrank This is not a defense of C or whatever, it's just Annoying

@justinfrank You have null pointers now though if your index is invalid

@hazel yeah but now it's an index out of bounds error that panics and halts execution, rather than a nasty segmentation fault that in practice panics and halts execution

@justinfrank I'm currently experiencing a nightmare issue where I'm trying to build up an AST. The issue is that this either needs:

1. a zipper (this is nightmarish to write in Rust)
2. a complicated tree traversal (not O(1))
3. a bunch of mutable references (not possible in Rust)

so instead I'm converting the AST into a representation in a SlotMap and then going back and forth between the two representations.

The thing is that I'm just turning the recursive type into... a recursive type, except instead of actual recursion, you just have memory addresses. into the SlotMap.

@hazel ouch, I guess I've been luckier with the algorithms I've needed to write in Rust, cause I've never needed to resort to that

@justinfrank I quite literally cannot think of a better way to do this. Every option is a horrible hack. And when you ask any Rust programmer about it, they don't know what you're talking about since Rust programmers don't really seem to tend to do this stuff I guess?

@justinfrank I feel like the Rust experience with anything self-referential is someone saying "that's a bad design choice", and then refusing to say how else to do it

Since, yeah, it's a bad design choice. The ownership type system inherently does not work with this kind of thing. But sometimes you just gotta

@hazel @justinfrank I'd never thought of it that way before but you're right. "Just index into a Vec" does seem to be one of the basic techniques of rust programming. I first did it in exasperation after trying for too long to implement a circular linked list the "right way" for an advent of code problem. It works well enough, but lots of potential to leak memory in a real-world scenario.

@petrichor @justinfrank Right, allocation is allocation, whether it happens in literal memory or inside a data structure you make inside that memory

@hazel @petrichor it occurs to me that this is really separating the logic for where some data is stored from the logical relationships between data, because sometimes the latter doesn't map well onto the former, which is the flexibility you get with garbage collection

@justinfrank @petrichor I guess this is the problem with systems programming as a whole, is that you can't really make a clean break between the way data is stored and the way you think about the data.

@hazel @petrichor I would say that what makes it systems programming is that the main way you think about the data is how its stored

@justinfrank @hazel Well, I guess this is a common enough complaint that an interface for allocators is getting into the standard library: doc.rust-lang.org/std/alloc/tr

And there are a few crates that implement the pattern in a reasonably general way, which saves me doing it badly every time I want one:
lib.rs/crates/typed-arena
lib.rs/crates/bumpalo

@hazel @justinfrank i was asking around how i should do a cyclic graph and it was all just "put it in a Vec"

@hazel @justinfrank or people telling me to use weak references and Arc

Sign in to participate in the conversation
types.pl

A Mastodon instance for programming language theorists and mathematicians. Or just anyone who wants to hang out.