Live data from Hacker News

Making C++ safe without borrow checking, reference counting, or tracing GC

verdagon.dev

91–100 of 226 posts

Re: Making C++ safe without borrow checking, reference counting, or tracing GC

#91
post #88

> Borrow checking is incompatible with some useful patterns and optimizations (described later on), and its infectious constraints can have trouble coexisting with non-borrow-checked code. Not that this isn't true, but the rest of the article introduces a system with a superset of those limitations, gradually decreasing over time but never becoming a subset. In fact the pattern described in the article is a common pa…

> In fact the pattern described in the article is a common pattern in Rust and I make use of it all the time; the library for making use of it is `slotmap`. Slotmap uses unsafe everywhere, it's a memory usage pattern not supported by the borrow checker. It's basically hand-implementing use-after-free and double-free checks, which is what the borrow checker is supposed to do. Is that really a common pattern in Rust?

> Slotmap uses unsafe everywhere, it's a memory usage pattern not supported by the borrow checker. Is disabling the borrow checker really a common pattern in Rust?

Wrapping "unsafe" code in a safe interface is a common pattern in Rust, yes. There is absolutely nothing wrong with using "unsafe" so long as you are diligent about checking invariants, and keep it contained as much as possible. Obviously the standard library uses some "unsafe" as well, for instance.

"unsafe" just means "safe but the compiler cannot verify it".

Unsafe does not disable the borrow checker, though. All of the restrictions of safe Rust still apply. All "unsafe" does is unlock the ability to use raw pointers and a few other constructs.

https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html#unsa...

Re: Making C++ safe without borrow checking, reference counting, or tracing GC

#92
post #91
post #88

Earlier quoted context omitted.

> In fact the pattern described in the article is a common pattern in Rust and I make use of it all the time; the library for making use of it is `slotmap`. Slotmap uses unsafe everywhere, it's a memory usage pattern not supported by the borrow checker. It's basically hand-implementing use-after-free and double-free checks, which is what the borrow checker is supposed to do. Is that really a common pattern in Rust?

> Slotmap uses unsafe everywhere, it's a memory usage pattern not supported by the borrow checker. Is disabling the borrow checker really a common pattern in Rust? Wrapping "unsafe" code in a safe interface is a common pattern in Rust, yes. There is absolutely nothing wrong with using "unsafe" so long as you are diligent about checking invariants, and keep it contained as much as possible. Obviously the standard libr…

It's essentially a "user-space" memory allocator with it's own use-after-free and double-free checks, apparently because the language implementation isn't adequate. If anything it just reinforces the articles point that "borrow checking is incompatible with some useful patterns and optimizations."

Re: Making C++ safe without borrow checking, reference counting, or tracing GC

#93
post #92
post #91

Earlier quoted context omitted.

> Slotmap uses unsafe everywhere, it's a memory usage pattern not supported by the borrow checker. Is disabling the borrow checker really a common pattern in Rust? Wrapping "unsafe" code in a safe interface is a common pattern in Rust, yes. There is absolutely nothing wrong with using "unsafe" so long as you are diligent about checking invariants, and keep it contained as much as possible. Obviously the standard libr…

It's essentially a "user-space" memory allocator with it's own use-after-free and double-free checks, apparently because the language implementation isn't adequate. If anything it just reinforces the articles point that "borrow checking is incompatible with some useful patterns and optimizations."

Eh? This is a wild take. How do you draw the conclusion the default implementation is inadequate?

Re: Making C++ safe without borrow checking, reference counting, or tracing GC

#94

Earlier quoted context omitted.

I really love parts of rust and kinda hate other parts. but this is what really ruins it for me. I want to play. I want to knock something together and work with it and see what kind of shape it is. rust demands that I cross every last t before I can run it at all. which is great if you already have a crystal notion of what you are building

> rust demands that I cross every last t before I can run it at all. It's worse than that IMO. Rust makes it very awkward/impractical to have cyclic data structures, which are necessary to write a lot of useful programs. The Rust fans will quickly jump in and tell you that if you need cycles, your program is wrong and you're just not a good enough programmer, but Maybe it's just that the Rust borrow checker is too li…

> currently can't do better

The limitations are an inherent consequence of basic tenets of Rust's design. Rust wouldn't be Rust anymore if you fixed them.

> Some of the restrictions of the Rust borrow checker and type system are arbitrary. They're there because Rust currently can't do better. They're not the gospel, they aren't necessarily inherent property that must always be satisfied for a program to be bug free. The Rust notion of safety is not an absolute. It's a compromise, and a really annoying, tiresome drain on motivation and productivity sometimes.

Yeah, but this actually seems consistent with the philosophy behind Rust: to take away the tools a programmer needs for creativity, so they couldn't do potentially costly mistakes, as applicable to big teams in huge corporations. Another commenter in this thread put it nicely: the borrow checker is a straitjacket for the programmer.

It's not meant to foster creativity, it's meant to be safe for big business and novice employees.

Re: Making C++ safe without borrow checking, reference counting, or tracing GC

#95
post #14

> Tracing GC is the simplest model for the user, and helps with time management and development velocity, two very important aspects of software engineering. > Borrow checking is very fast, and helps avoid data races. One thing many people seem to assume is that not having to care about memory means you can program faster and get to your goal faster. As the author here seems to do. However as it turns out, if your pr…

I don't write Rust. But here is what you said and what the author said don't conflict with each other, and it has been on my mind for a while. People who write similar code, or work on things for decades usually don't really think through what "sketch out some code" looks like. They spend most of their time on refactoring things that has clear use-cases, but not well-defined API boundaries within the component, or be…

> Ownerships, even nullability checks are not helpful

Memory management does get on the way. But you are wrong about algebraic data types, they will help you sketch something.

Ideally, if you don't know what you want, you will want extendable¹ algebraic types, more like Type Script than Rust, but what you call "nullability check" is a benefit since the beginning.

1 - Where you can say "here comes a record with those columns" instead of "here comes this record". You can write this in Rust, but it's easier to simply completely define everything.

Re: Making C++ safe without borrow checking, reference counting, or tracing GC

#96
post #56
post #49

Earlier quoted context omitted.

Because implementing a new language and getting it to wide adoption is an enormously challenging task, with a much lower success rate than e.g. SV startups. Languages that try to implement one new bright idea don't go anywhere, because that's not enough to cause people to switch. At best they serve as examples for feature adoption in other languages. Look at Rust for example: it seems to be succeeding and gaining ado…

> it's taken 17 years to get to this point Yes and no. Rust went through quite a bit of changes early on, ro the point that it's not really that similar of a language, and 1.0 was released in May 2015. That's still quite a while (8 years), but IMO doesn't quite mean the same thing as a language that's been around for 17 years with a similar level of adoption. My impression (from the outside) is that Rust usage is sti…

While that is true about Rust, most new languages are gonna have the same thing. It'll be years before they get to 1.0. Look at Zig, just about every new language. So I don't think it is valid to discount the 1.0 days because all languages are gonna need awhile to get to the 1.0 day. It still took 17 years of time investment to get Rust to where it is today.

Re: Making C++ safe without borrow checking, reference counting, or tracing GC

#97
post #8

Earlier quoted context omitted.

Presuming syntax for “unsafe” that gracefully degrades in non-aware compilers, why couldn’t a particular compiler start doing it right now, starting with a very trivial safety checker than can be iteratively improved upon once the framework is in place?

I feel like D has gone this route of incrementally adding features (like borrow checking) to the language that, in principle, improve safety. I wonder if anyone here has more experience to know how well it has worked? One massive advantage of Rust is that they started with borrow checking from the beginning. I think one thing that often gets understated in these discussions is how much it matters to have your entire…

It still hasn't, that has been unfortunely a common theme in D's evolution, chasing the next big idea that will this time bring folks into D, while leaving the previous ones half implemented with bugs.

So now there is GC and @nogc, lifetimes but not quite, scoped pointers, scoped references,... while Phobos and ecosystem aren't in a state to fully work across all those variations.

Re: Making C++ safe without borrow checking, reference counting, or tracing GC

#98
post #83

Earlier quoted context omitted.

Difficult to answer. However, what you can say is that the borrow-checker works like a straight-jacket for the programmer, making them less capable to focus on other things like performance issues, high-level data leaks (e.g. a map that is filled with values without removing them eventually), or high-level safety issues.

You can also say that the borrow checker works like a helpful editor, double checking your work, so that you can focus on the important details of performance issues, safety issues, and such, without needing to waste brain power on the low-level details.

This would be true if code using the borrow checker was easier to read than to write.

Re: Making C++ safe without borrow checking, reference counting, or tracing GC

#100
post #93
post #92

Earlier quoted context omitted.

It's essentially a "user-space" memory allocator with it's own use-after-free and double-free checks, apparently because the language implementation isn't adequate. If anything it just reinforces the articles point that "borrow checking is incompatible with some useful patterns and optimizations."

Eh? This is a wild take. How do you draw the conclusion the default implementation is inadequate?

Because something like slotmap has to use `unsafe` to get around the inadequacies of the borrow checker...
Post reply on HN