Ask HN: What should have been the term for RAII?
Bjarne Stroustrup himself said he was very busy when he came up with the name for this concept, that it’s not a very good name, and joked he’s not good at “marketing“.
What would be a better terminology?
As I’ve been learning modern C++, I admit that I’ve struggled to understand why these terms make sense. To me, I think of it like “Resource Acquisition Promising Release”. Does this betray that I am not truly understanding Strourstrup’s principle?
61 comments
[ 2.6 ms ] story [ 32.2 ms ] threadFor C++ and Rust there might not be a well defined scope since objects can be „moved“. Eg a method constructing an object can return it to the caller without the destructor being called.
You can do
Also Go's defer keyword, which is bound to the current function (defer until function returns).std::mem::forget is considered safe, as explained in its docs: https://doc.rust-lang.org/std/mem/fn.forget.html
``` (call-with-output-file some-file (lambda (out) (write 'hello out))) ```
RAII isn't about scope, it's about lifetimes that can persist beyond the instantiating scope. More like object-bound resource management.
"Lifetime" is a normative term in ISO C. In the 1999 standard, it is given as: "The lifetime of an object is the portion of program execution during which storage is guaranteed to be reserved for it. An object exists, has a constant address, and retains its last-stored value throughout its lifetime." (6.4.2 Storage Durations of Objects)
"Lifetime" appears three times in the Index of the 1988 edition of Compilers: Principles, Techniques and Tools by Aho, Sethi and Ullman (a.k.a. the Red Dragon Book).
Lifetime, of a temporary 480
Lifetime, of an activation 391, 410
Lifetime, of an attribute 320-322, 324-329
The earliest mention of this idea (CADR / CADRe) I’ve found is from 2012: https://groups.google.com/a/isocpp.org/g/std-proposals/c/Una...
Who is that for? Dummies who get it backwards? Oh, look, you're releasing in your destructor and acquiring in the destructor. Did you forget your CADR?
I even had my own proposal 5 years ago for improving that!
> That's right, but I would go one step further and have F(irst) and R(est), with obvious composition as follows: (using kruhft's examples from another thread)
> I would argue that it's worth sacrificing the 'f' and 'r' symbols for such a common construct.> …
> Yes, I realize I'm 55 years late to the party.
https://news.ycombinator.com/item?id=13259344
Now we only need to implement both changes at the same time! :-P
Only when the tree structure conforms to certain conventions and intent of representing a list is the car "first" and the cdr "rest".
So of course those names are fine for nested lists: (ff '((a b c) d)): the "first of the first". But in, say, an assoc list ((a . 3)) 3 is not the "rest" of anything; it's the value of the key a.
The proposed functions go with the first and rest functions, rather than replace the cddr ones.
Now let's talk about something else: the order. In caddr, the order is just a condensation of the nested application of (car (cdr (cdr ...))), in the same order: it's easy to convert between the two, both actually and mentally. However, in left to right threading syntax, it's backwards:
corresponds to so it condenses like You can see someone wanting a variant which has the letters in the opposite order.With f and r functions, you can do:
which is almost the backwards "ffr" you might want.If the constructor throws an exception, the destructor is called immediately.
> Resource Acquisition Is Initialization or RAII, is a C++ programming technique[1][2] which binds the life cycle of a resource that must be acquired before use (allocated heap memory, thread of execution, open socket, open file, locked mutex, disk space, database connection—anything that exists in limited supply) to the lifetime of an object.
I’d crib the name from Rust, this is ownership, where the object owns the resource.
Also, see related video here
Here's one important difference: Destructors work in standard data structures. If for whatever reason you want to build a map<string, list<fstream>>, and the map goes out of scope, all files are correctly closed. (Rust's drop semantics work the same way.) That's a lot more work in Java or C#.
Yes, that means they hang around a lot longer, and that's sometimes problematic, but that's the GC way.
For resources like memory, where it’s merely a question of performance, I would agree. But some resources have correctness implications. Files, for example, you often want to close deterministically. It’s simply a terrible experience if a user can’t save because a file handle from a previous operation still lingers in a GC queue somewhere.
That’s also the reason why language features like try-with-resources were added in the first place.
Resource Is Getting Guaranteed to End up Destructed.
I try to have RIGGED as backronym, but the words are not completely right. Even so, the slogan could work like this: Prefer using RIGGED resources in C++
I've tried reconciling how its defined here:
https://en.cppreference.com/w/cpp/language/initialization
However, it seems like wording describing ideas around how a resource is created, and not how it's completed.