Hacker News new | ask | show | jobs
by notacoward 2633 days ago
> It would make sense ONLY if you want to have a new language.

Are you seriously suggesting that C++ with defer is a new language? Unlike, say, C++ with lambdas? That's just silly.

1 comments

C++ without deterministic destructors to manage lifetime would be a (fundamentally) different language.

Furthermore, also disagree with you that it would be a better language. C++ has many warts but object lifetime and RAII is amongst its strong suits (unarguably, I thought — yes, resource lifetime is complex, but it’s inherently so; C++ just makes the complexity explicit and handles it in a good way). Handling resource lifetime in languages with nondeterministic GCs can be such a pain that it has fundamental, detrimental impact on the architecture. Just look at .NET’s handling of `Dispose`. I’ve written a ton of .NET GUI code, and handling resource lifetime (in particular GDI+) is an absolute pain point, which is uniquely caused by the lack of deterministic object lifetime.

> C++ without deterministic destructors to manage lifetime would be a (fundamentally) different language.

The problem is that it's not usefully deterministic once you add in exceptions, shared pointers, move semantics, lambda captures, etc. Not to mention every perverse combination of those things. Yes, it's deterministic in the tautological sense that almost everything is deterministic given enough information, but I'm not sure that's enough even for the people who write the compilers. Even they have bugs related to misunderstanding this "deterministic" system. I certainly wouldn't want to make it less deterministic, and defer certainly doesn't make it so.

> resource lifetime is complex, but it’s inherently so

A certain amount of complexity is natural, a certain amount is spurious and self-inflicted. See above for some of the causes of that spurious complexity.

> C++ just makes the complexity explicit

Being explicit about memory management isn't a goal. C is even more explicit about these things. Does that make it a better language? Even in C++, new/delete is more explicit than most of the current idioms, and every book on modern C++ recommends against them. Explicit memory management should be a last resort, for the cases not handled cleanly by the language's other constructs, and those should be kept to a minimum. C++ has notably failed at that. Literally every other popular language except for C does better.

> Handling resource lifetime in languages with nondeterministic GCs can be such a pain

Do you really see no alternatives between dumping all memory-management complexity on the programmer and a full tracing GC? The authors of Objective C's automatic reference counting or Rust's borrow checker might take issue with that, as would the people who developed the memory-lifetime rules and infrastructure for all of the bigger older C codebases I mentioned in another comment. It is in fact possible for object lifetimes to be far more deterministic than in C++ as it exists today, and I for one think that would be a good thing.

> The problem is that it's not usefully deterministic once you add in exceptions, shared pointers, move semantics, lambda captures, etc.

No, it really is, even in the presence of the things you mentioned. That’s the whole point.

> Being explicit about memory management isn't a goal. […]

I get the impression that you’re confusing explicit and manual memory management. They’re not the same.

> Do you really see no alternatives between dumping all memory-management complexity on the programmer and a full tracing GC?

Of course I do, but the alternatives aren’t without their own problems. I’m curious how Rust will fare but Objective C’s ARC, while attractively simple, has performance implications, and then there’s the problem with cycles.

Rust has ARC and RC, which I gather are badly overused by refugees from other languages dependent on GC.

The better programs and libraries use them less. It remains to be seen whether this aesthetic will win out.

> The problem is that it's not usefully deterministic once you add in exceptions, shared pointers, move semantics, lambda captures, etc. Not to mention every perverse combination of those things.

It really is though, and I can't stress that enough. I feel you just throwing out keywords to make it sound more complex than it is.

> I can't stress that enough.

You can stress an untrue statement all you like. Shout it to the heavens. It will still be untrue.

Thought for you to consider: the behavior might seem predictable to you but that's not a relevant standard. A chess opening, a volleyball play, a snowboard run might all seem straightforward to me, but that doesn't mean they'd suit everyone. It doesn't mean they're the best. It just means I've invested my time in learning to do those things those ways. It's too easy to say everyone should have to memorize the same lists of rules, to retreat into "we don't care about the blubs" arrogance, ignoring the fact that it just doesn't have to be that way. It is in no way necessary, for any purpose, to make every single programmer in a language spend so much of their time looking over their shoulder to make sure the compiler is doing the right thing. It's a waste no matter how good those programmers are.

> I feel you just throwing out keywords

And I feel that you're just not even trying to understand their relevance because you've already decided on a conclusion. The lengths to which people in this thread go to rationalize the time they've already wasted is astonishing. People who use C++ should be the first to demand its improvement, but I guess not all humans are rational.

You might have picked the wrong hill to die on.

C++ destructors really are deterministic, even in the face of exceptions, lambdas, and moves: everything constructed gets destroyed. Modern wrinkles where the compiler is allowed to skip a construction and a destruction do not contradict that. You have to fool with heap memory or evoke UB to escape that law.

To be useful, determinism has to mean not only that something happens but that it happens at a predictable time. Otherwise you're into that tautological "everything is deterministic" territory, and you step into that even deeper when you acknowledge the "modern wrinkles". "Compiler is allowed" (but not required) is practically the definition of non-determinism.
The behavior is predictable to anyone versed in the language. C++ is a complex language to learn so that is inherently harder than most alternatives, but the concepts here are not.

I am first in line to acknowledge the flaws of C++ as well as sheering on more modern approaches. But I do find your criticisms shallow and a quite oddly chosen.

> The behavior is predictable to anyone versed in the language.

Ahh, there's that "don't care about the blubs" arrogance again. Never mind that your interlocutor is about 99.9% likely to be less of a blub than you are. Whether behavior is predictable given arbitrary amounts of information and effort is not the point. What matters is how much it distracts the programmer from the non-language-specific problem they're really trying to solve, and the answer for C++ remains way too damn much even when the programmer is highly skilled and well versed in the language.