> I can't say I've ever seen someone manually implement Arc in C
In C++, shared_ptr in the standard. But this was common even before the c++11 standard introduced that. I've rolled my own before, more than once. Microsoft ATL had CComPtr.
It wasn't surprising to me either that rust came from Mozilla, which made heavy use of COM, an object model that is very heavily based on reference counting.
Anyway, what do you prefer to lifetimes? They go back to at least the 60s with lisps and algol and possibly earlier. I wouldn't be surprised to find that idea predates electromechanical computers entirely.
To your second question, writing C I like to let the scope dominate the lifetime by doing a free as soon as an object goes out of scope. To make something borrow, you assign it to something with a different scope, then assign your local copy to NULL, exploiting the fact that free(NULL) is a well behaved no-op. In c++ you do the same but you can use destructors to make it more automatic.
I agree with them that in any well-written program (in any language really, not just C and C++) the ownership and lifetime constraints are not necessarily enforced by the compiler - that is, they are not expressed through types or even necessarily through code at all - but they are definitely existent in the design and behaviour of the system. If the programmer cannot explain who holds what and for how long, and therefore when it's safe to read or write particular resources, then that isn't well-written code IMO.
> I can't say I've ever seen someone manually implement Arc in C
...an Arc is literally just a shared pointer. It's in the name, Atomically Reference Counted. Reference counted resources that use atomic operations to adjust the count are a dime a dozen in C projects in my experience.
Rust did not invent the concept of a multiple-reader/single-writer lock either, e.g. the Linux kernel has the `rw_semaphore` type. I don't understand treating types like this as something arcane simply because they're given an explicit tag in Rust.
In short, RAII and smart pointers and borrow checker are all signs of "individual element thinking" and that way lies madness. You smear out lifetime and ownership so badly that it practically by definition becomes a problem.
Your goal is to think about this stuff in groups to make thinking about allocation way, way easier. Programming is all about abstracting to the next layer.
I'm not sure he has quite gotten to the heart of the issue, yet. However, a bunch of smart people (Casey Muratori, Jonathan Blow, Andrew Kelley, etc.) are all dancing around something that Rust and C++ don't seem to fit the bill on. Hopefully they can crystallize it out so that everybody can see it.
But actually it's suggesting how I've been wanting memory to be managed for a couple decades (and have achieved long ago in C projects). Basically some sort of "domain-orientated arena allocator". A simple example is in a network server -- you receive a request from a client, do a bunch of stuff to service that request, and now you're done. Please blow away the memory used to service the request, thanks, all at once. Of course it's not quite that simple because there will be some "chaff" objects thrown off in processing the request that we need to keep around for a while later (e.g. for logging to drain).
I suppose the reference to Jonathan Blow should have been a clue that this would be something worthwhile.
I disagree here. For example, try writing something that does reference counting in C vs C++. In C++, it's practically trivial. In C, it's a nightmare of bugs. RAII support being directly in the language is huge in this case.
And Andrew Kelley writes compilers. And arenas still appear to be superior.
Games and compilers seem to do better with custom allocators. Embedded almost always static allocates. GPU workloads generally don't have "heap-like" allocations either.
We have an increasing amount of evidence that "malloc-like" or "heap-like" allocations on an individual level seem to be a net negative.
My gut feel, as someone with a grey beard, is that we're looking at a breakpoint like we did with garbage collection.
Garbage collection absolutely suuuuucks until you get big enough memory that you can overallocate by about a factor of 2 at which point garbage collection flies.
I think we're at a similar point in "systems programming". It's now okay to overallocate, overcopy, and especially overcalculate things due to current CPU architectures. Chasing pointers is now mega-bad so vtables and the like are becoming a performance bottleneck.
Some embedded nowadays has hundreds of megs of RAM, with its application using mmap, out of an overcommitted virtual memory.
Is Andrew pro-arenas for compilers? I have seen him preach re: data oriented design, and Zig certainly does more re: allocators than Rust, but do you have more info re: this claim?
And Rust brings more to the table than just the borrow checker.
Time will tell.
I'd call it object-oriented thinking. To me Rust and modern C++ are attempting to "OO-ify" systems programming and I think you get push back from folks who view their resources more holistically.
In my experience “de-programming” OOP-programmers is one of the first things teams I’ve been have had to do so that said OOP devs have a better time and write more idiomatic code.
That said, most of the time, I find myself utilizing group oriented thinking in my codes and I avoid atomistic, reductionist thinking whenever analyzing a problem at a first pass, but reductionist reasoning does help at times, it just depends on the problem and the context. It is also true, unfortunately, that in science teaching at least we teach students to be reductionist first, and then that reductionist thinking clouds their understanding and it is something young scientists need to break out of at some point, and some never do break out of it. May be in that way it's similar to what this person refers to here (n vs n+1) I just didn't also get stuck thinking reductionism is always bad and avoided it as a rule but I draw from both sides, so to speak.