Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Zig doesn't even have RAII...
 help



which is a good thing. C++'s RAII is magic-sauce that does a lot for you when you can simply use `defer` in zig. A constructor is just a function call. A destructor is just a function call.

And a function call is just a fancy JMP, still it's generally acknowledged to be better to have all the bookkeeping automated.

Does defer in zig track the objects lifetime directly, or is it like the various other 'context' features in other languages where it only really works for lifetimes of function-local variables and leaves you on your own when things get more complicated? (which, IMO, is precisely when RAII becomes most useful. It does seem like most of these languages only consider the 'forgetting to cleanup on an early return from a function' case)

Constructors and destructors are also just function calls in C++

And you can't forget to type defer


It's not a good thing. The reasoning is extremely simple and I don't understand how can anyone oppose it: there are some operations that you don't want to forget BY DEFAULT.

If I open a file, eventually I want to close it. If I allocate some memory, eventually I want to deallocate it.

Any programming language design that intentionally puts the onus BY DEFAULT on the user to *not forget to manually do something* is honestly asinine.

Defer has a place (I do use defer in C++, in fact you can implement it with RAII, proving that RAII is strictly more powerful/more flexible), but the default should be the safest and most straightforward option.

Also "magic-sauce that does a lot for you" is just false. It's literally a function call injected at the end of a scope.


How is defer not magic sauce?

Whether you consider it magic is up to you, but, unlike a destructor in RAII, there is nothing automatic going on. If you don't explicitly invoke a destructor, you won't get a destructor.

The fact that you can explicitly invoke the destructor to happen later is simply syntactic sugar, just like if/else/while, or any other control construct more powerful than a conditional jump instruction.


And more importantly, you can choose what destructor to call. This is perhaps what's most underrated about defer, because defer can select among many different destructors possible, at multiple different levels (group free with arenas, individual free, etc).

Or even whether you need a destructor, or something simpler, like nulling out a pointer or two to break a reference loop.

defer is a perfectly general structured flow concept; it only cares about when you do something, and is completely orthogonal to what you need to accomplish.


I'm not sure the folks responding can tell the difference.

> If you don't explicitly invoke a destructor, you won't get a destructor.

When you explicitly invoke a "destructor", you do it on many code paths (and miss one or two)

>The fact that you can explicitly invoke the destructor to happen later

You don't specify where the `defer`-red "destructor" will be invoked.


> When you explicitly invoke a "destructor", you do it on many code paths (and miss one or two)

Unless, of course, you do it inside a defer block.

> You don't specify where the `defer`-red "destructor" will be invoked.

Yes, actually, you do. It is patently obvious, by code inspection, where the destructor, or anything else specified in a deferred block, will be invoked. defer is a perfectly cromulent part of structured control flow, allowing for easy reasoning about when things occur without having to calculate an insane number of permutations of conditional branch instructions.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: