Live data from Hacker News

Under the hood: Vec

marma.dev

21–30 of 142 posts

Re: Under the hood: Vec<T>

#21
post #6

I love how it shows that you can have both performance and safety without jumping through hoops. The little details of memory management really shape how we end up writing code, often without even noticing. Rust makes it possible to get close to the hardware while still keeping you out of the usual trouble spots. It’s one of those things you appreciate more the longer you use it

Erm what? The article contradicts this. I'd push back on "without jumping through hoops". The article itself demonstrates 6 layers of abstraction (Vec -> RawVec -> RawVecInner -> Unique -> NonNull -> *const u8) built on unsafe primitives. The standard library does the hoop-jumping for you, which is valuable, but the hoops exist, they're just relocated.

I bet Vec's implementation is full of unsafe blocks and careful invariant management. Users face different hoops: lifetime wrangling, fighting the borrow checker on valid patterns, Pin semantics, etc. Rust trades runtime overhead for upfront costs: compile-time complexity and developer time wrestling with the borrow checker which is often the right trade, but it's not hoop-free.

The "close to hardware" claim needs qualification too. You're close to hardware through abstractions that hide significant complexity. Ada/SPARK gives formal correctness guarantees but requires proof effort and runtime checks (unless you use SPARK which is a subset of Ada). C gives you actual hardware access but manual memory management. Each has trade-offs - Rust's aren't magically absent.

Re: Under the hood: Vec<T>

#22
post #9
post #6

I love how it shows that you can have both performance and safety without jumping through hoops. The little details of memory management really shape how we end up writing code, often without even noticing. Rust makes it possible to get close to the hardware while still keeping you out of the usual trouble spots. It’s one of those things you appreciate more the longer you use it

I come from a Swift/Kotlin background and I've been learning Rust for fun in my spare time From what I heard online I was expecting it to be a lot harder to understand! The moving/borrowing/stack/heap stuff isn't simple by any means, and I'm sure as I go it will get even harder, but it's just not as daunting as I'd expected It helps that I love compiler errors and Rust is full of them :D Every error the compiler catc…

The language and associated tooling keep improving.

Over the course of the last decade I've made several attempts to learn Rust, but was always frustrated with having code that reasonably should compile, but didn't and I had to run the build to even find that out.

Now we have rust-analyzer and non-lexical lifetimes, both tremendously improving the overall experience.

I still don't enjoy the fact that borrows are at the struct level, so you can't just borrow one field (there's even a discussion on that somewhere in Rust's) repo, but I can work around that.

To drive the point home: I'm a frontend developer. This is a very different environment compared to what I'm used to, yet I can be productive in it, even if at a slower pace in comparison.

Re: Under the hood: Vec<T>

#23
post #9

Earlier quoted context omitted.

I come from a Swift/Kotlin background and I've been learning Rust for fun in my spare time From what I heard online I was expecting it to be a lot harder to understand! The moving/borrowing/stack/heap stuff isn't simple by any means, and I'm sure as I go it will get even harder, but it's just not as daunting as I'd expected It helps that I love compiler errors and Rust is full of them :D Every error the compiler catc…

> It helps that I love compiler errors and Rust is full of them :D Every error the compiler catches is an error my QA/users don't amen! I despise Python even though I used to love it, and that's because it's full of runtime errors and unchecked exceptions. The very instant I learned more strongly typed languages, I decided never to go back.

And then comes the point, where you get a scenario, which is actually, you'd think, at least, something simple, but then gets really tough to express in strongly, statically typed languages, and you might take a step back and consider for a moment, how simple it would be to express this in a language like Python, while still being memory safe.

Statically typing things is great, and I enjoy it too, when it is practical, but I don't enjoy it, when it becomes more complicated than the actual thing I want to express, due to how the type system of that particular language or third party tool (in Python) works.

Re: Under the hood: Vec<T>

#24
post #15
post #8

Earlier quoted context omitted.

Oh, I never knew that Rust had variance. I always just assumed everything was invariant. Strange that they've got no way to write it down in the type system.

In prehistoric Rust, variance used to be named more explicitly. However, the terminology of covariant and contravariant subtyping of lifetimes is a language theory jargon. This is the right perspective for language design, but programmers using the language don't necessarily use these terms. It's been replaced with a "by example" approach. It's much easier to teach it: just add a fake field that acts if you had this…

Variance is an absolute disaster when it comes to language pedagogy. One of the smartest things Rust ever did was avoiding mentioning it in the surface-level syntax.

Re: Under the hood: Vec<T>

#25
post #8

Earlier quoted context omitted.

Oh, I never knew that Rust had variance. I always just assumed everything was invariant. Strange that they've got no way to write it down in the type system.

https://doc.rust-lang.org/reference/subtyping.html#variance Lifetimes imply the need for the idea of variance.

Rather, any language with both generics and subtyping needs to consider variance, and Rust doesn't have subtyping in general, but lifetimes do technically have subtyping relationships, so lifetimes are the only place where this matters, and fortunately Rust can just infer the right behavior based on some simple type-level heuristics.

Re: Under the hood: Vec<T>

#26
I'm sure all these layers are good engineering and provide meaningful safety guarantees, but it sure makes the code harder to understand if you want to see how things are implemented.

Another example, I was trying to see how i64::isqrt is implemented, but first you have to wade through layers of macros

Re: Under the hood: Vec<T>

#27

I'm sure all these layers are good engineering and provide meaningful safety guarantees, but it sure makes the code harder to understand if you want to see how things are implemented. Another example, I was trying to see how i64::isqrt is implemented, but first you have to wade through layers of macros

This is just how rust and c++ code is in my experience.

Re: Under the hood: Vec<T>

#28
post #7

While safe Rust may be relatively simple to write, and certainly easier to write than safe C, this article has someone added to my belief that unsafe Rust is far too difficult to write. Perhaps some of this is deliberate, as a kind of defence mechanism against people using it willy-nilly, it still seems over-designed.

Yes, it is indeed very difficult to write unsafe rust, also very difficult to write anything low level and reusable

Re: Under the hood: Vec<T>

#29
post #6

I love how it shows that you can have both performance and safety without jumping through hoops. The little details of memory management really shape how we end up writing code, often without even noticing. Rust makes it possible to get close to the hardware while still keeping you out of the usual trouble spots. It’s one of those things you appreciate more the longer you use it

Erm what? The article contradicts this. I'd push back on "without jumping through hoops". The article itself demonstrates 6 layers of abstraction (Vec -> RawVec -> RawVecInner -> Unique -> NonNull -> *const u8) built on unsafe primitives. The standard library does the hoop-jumping for you, which is valuable, but the hoops exist, they're just relocated. I bet Vec's implementation is full of unsafe blocks and careful i…

Most of those are abstractions, but not a runtime overhead. NonNull even enables an optimization not available to most other languages.

And you can wonder, is this accidental complexity? Or is this necessary complexity?

Re: Under the hood: Vec<T>

#30
post #6

I love how it shows that you can have both performance and safety without jumping through hoops. The little details of memory management really shape how we end up writing code, often without even noticing. Rust makes it possible to get close to the hardware while still keeping you out of the usual trouble spots. It’s one of those things you appreciate more the longer you use it

Erm what? The article contradicts this. I'd push back on "without jumping through hoops". The article itself demonstrates 6 layers of abstraction (Vec -> RawVec -> RawVecInner -> Unique -> NonNull -> *const u8) built on unsafe primitives. The standard library does the hoop-jumping for you, which is valuable, but the hoops exist, they're just relocated. I bet Vec's implementation is full of unsafe blocks and careful i…

It's fine https://github.com/model-checking/verify-rust-std/issues/283 https://github.com/model-checking/verify-rust-std/pull/481 (But until two weeks ago, it wasn't - you could in theory cause UB by writing purely safe code within the Vec implementation.)
Post reply on HN