3 ms·
I don't have to think about them, and I can't get them wrong. ... until you have to write a class yourself. Then you have to think of the complexities introduc
by papaf 5y ago
I don't have to think about them, and I can't get them wrong.
... until you have to write a class yourself. Then you have to think of the complexities introduced by destructors such as copy semantics, move semantics and the destructors themselves.
You also have to deal with architectural questions such as should my file have a close method (C++) or do I always leave this to the destructor (Rust).
If I was to give an opinionated summary, a little complexity at the call site has been moved to a lot of complexity in the class implementation. Since there is, on average, one class implementation to many object uses, destructors might be considered a win. But I don't feel so strongly about it that I wouldn't consider a language for not having destructors.
- ncmncm 5y agoYou almost got there. What makes a language powerful is the ability to put essential semantics into a library where they can be got right once, so all users of the library benefit. It is worth design, implementation, testing, optimization effort if the results can be delivered over and over, in many different contexts, reliably. Destructors are the necessary ingredient to pull transaction semantics into libraries. Without, you are left to write comments explaining users' responsibilities, and users have to read and act on them perfectly, or be wrong. With, you can code them correctly once and users have no opportunity or temptation to get them wrong.
- papaf 5y agoI agree with your comment about libraries. Destructors biggest advantage is in well used libraries. Any interesting code involves custom classes written by less experienced developers that are only used once or twice in an application -- it is there that that the complexity of destructors hurt.
- ncmncm 5y agoThere certainly are design complexities in C++, around copy and move constructors and various operators. Some of those could have been avoided, in hindsight, and new languages can. None of those complexities spill over onto destructors. They were perfect in their original conception, and are unchanged 40 years on. They evoke no regrets. No bugs trace to anything unfortunate about destructors.
- masklinn 5y ago> ... until you have to write a class yourself. Then you have to think of the complexities introduced by destructors such as copy semantics, move semantics and the destructors themselves. That is a specific language issue. Rust doesn't share most of these concerns for instance, the only complexity is writing the Drop itself (which I agree can be subtle), but a type can't even be both Copy and Drop (and Rust has none of the Rule of X complexity of C++). > You also have to deal with architectural questions such as should my file have a close method (C++) or do I always leave this to the destructor (Rust). That seems less like an architectural question and more like a stylistic question. > If I was to give an opinionated summary, a little complexity at the call site has been moved to a lot of complexity in the class implementation. Except that's not actually true, much of the complexity you'll find in a destructor (excluding the complexities inherent and exclusive to C++ which nobody else is under any requirement to reproduce) will have to be implemented as whatever "cleanup" method is deferred. And then you need the defer system, and you need to actually call it which you can forget. So while destructors are definitely not trivial to add to the language, defer spreads the responsibilities and complexity arounds, and increases the occurrences of possible errors, as well as the number of failure modes. It also adds semantics ambiguities / complexities to the language: when you defer an expression, what is evaluated when? Dtors don't have that issue, you construct something according to normal language rules, then the dtor will be called at destruction.