Live data from Hacker News

Zig 0.8.0 Release Notes

ziglang.org

51–60 of 82 posts

Re: Zig 0.8.0 Release Notes

#51
post #45
post #31

Earlier quoted context omitted.

Actually, no, I mean destructors. Equivalent to Rust's Drop trait. Those are needed for RAII, but also for about everything else. (You need other things, too, to make RAII.) They were the only thing that made C++ uniquely powerful in 1985, and the only reason Rust can begin to compete. They represent the first and still only piece of runtime automation seen anywhere in the programming world. (Some would claim GC, but…

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…

> ... 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.

Re: Zig 0.8.0 Release Notes

#52
post #36

Earlier quoted context omitted.

> If you imagine destructors have something to do with memory management, you have much yet to learn. It is very limiting to think that destructors is the only way to solve resource scoping problem.

What alternative doesn’t add failure opportunities and require additional work by the developer where they will crop up? Both defer (and more generally scope guards) and context managers certainly do, to say nothing of try/finally.

Linear types can solve the problem. Also destructors tie design to stack frames. Limiting application for strictly nested code only.

Re: Zig 0.8.0 Release Notes

#53
post #41

Earlier quoted context omitted.

True, but also does RAII for heap allocated objects unless one makes use of smart pointers. Outside HN, CppCon and C++Now bubbles not all C++ codebases are as clean as we would wish them to be.

I don't understand the objection (?), I think there's at least one word missing, possibly more. If you want to use RAII for heap allocations you obviously need some sort of RAII wrapper for them. And smart pointers are the usual solution. But technically you can do without if you really really don't want to make dereference overridable, you can just have the "smart" bit (RAII / automatic deterministic deallocation) w…

What your obviously remark misses out is my second sentence "Outside HN, CppCon and C++Now bubbles not all C++ codebases are as clean as we would wish them to be.".

I have seen plenty of new std::string("some") and other similar crimes in offshored code, or code without ownership that gets updated by whatever external contractor got brought in to implement 5 Jira tickets that finally got some budget assigned to them.

To be fair this isn't exclusive of C++, I have seen similar bad practices in other languages, C++ just gives more opportunities for them.

Re: Zig 0.8.0 Release Notes

#54
post #52

Earlier quoted context omitted.

What alternative doesn’t add failure opportunities and require additional work by the developer where they will crop up? Both defer (and more generally scope guards) and context managers certainly do, to say nothing of try/finally.

Linear types can solve the problem. Also destructors tie design to stack frames. Limiting application for strictly nested code only.

> Linear types can solve the problem.

While that is true, I did not consider it worth mentioning given the context of the discussion. I still don't.

> Also destructors tie design to stack frames.

No more so than linear types.

Re: Zig 0.8.0 Release Notes

#55
post #53

Earlier quoted context omitted.

I don't understand the objection (?), I think there's at least one word missing, possibly more. If you want to use RAII for heap allocations you obviously need some sort of RAII wrapper for them. And smart pointers are the usual solution. But technically you can do without if you really really don't want to make dereference overridable, you can just have the "smart" bit (RAII / automatic deterministic deallocation) w…

What your obviously remark misses out is my second sentence "Outside HN, CppCon and C++Now bubbles not all C++ codebases are as clean as we would wish them to be.". I have seen plenty of new std::string("some") and other similar crimes in offshored code, or code without ownership that gets updated by whatever external contractor got brought in to implement 5 Jira tickets that finally got some budget assigned to them.…

> What your obviously remark misses out is my second sentence "Outside HN, CppCon and C++Now bubbles not all C++ codebases are as clean as we would wish them to be.".

Right, but we're not discussing C++ are we? We're discussing RAII. C++'s mistakes are C++'s mistakes, adding RAII to a language doesn't imply you have to replicate C++'s mistakes, nor are C++'s mistakes issues with the concept of RAII, or destructors.

Re: Zig 0.8.0 Release Notes

#56
post #44
post #40

Earlier quoted context omitted.

> The idea of including a C++ and a C compiler gratis is brilliant, and solves a big interoperability headache very elegantly. C++ did it first, having been born at same place as UNIX and C, all major C compiler vendors quickly added it into the box.

It would be better if a C or C++ header sufficed to declare things so they may be called directly from Zig, without need for matching declarations in Zig. Or, do they? For it to be useful, types would need to be imported, too. That would need destructor and overloading support. Which is doable.

Depends how much modern C and C++ Zig wants to implement in order to understand the types.

Generics, lambdas, concepts, templates, exceptions, ....

Re: Zig 0.8.0 Release Notes

#57
post #53

Earlier quoted context omitted.

What your obviously remark misses out is my second sentence "Outside HN, CppCon and C++Now bubbles not all C++ codebases are as clean as we would wish them to be.". I have seen plenty of new std::string("some") and other similar crimes in offshored code, or code without ownership that gets updated by whatever external contractor got brought in to implement 5 Jira tickets that finally got some budget assigned to them.…

> What your obviously remark misses out is my second sentence "Outside HN, CppCon and C++Now bubbles not all C++ codebases are as clean as we would wish them to be.". Right, but we're not discussing C++ are we? We're discussing RAII. C++'s mistakes are C++'s mistakes, adding RAII to a language doesn't imply you have to replicate C++'s mistakes, nor are C++'s mistakes issues with the concept of RAII, or destructors.

Had RAAI been properly implemented in C++, doing something like new std::string("something") should have been a compiler error.

From type theory point of view, ideally RAII aware types should only compose with outher RAII types without escape hatches.

Rust and Ada do it better in this regard.

Re: Zig 0.8.0 Release Notes

#58
post #44
post #40

Earlier quoted context omitted.

> The idea of including a C++ and a C compiler gratis is brilliant, and solves a big interoperability headache very elegantly. C++ did it first, having been born at same place as UNIX and C, all major C compiler vendors quickly added it into the box.

It would be better if a C or C++ header sufficed to declare things so they may be called directly from Zig, without need for matching declarations in Zig. Or, do they? For it to be useful, types would need to be imported, too. That would need destructor and overloading support. Which is doable.

That is how Zig works with C code:

- https://ziglang.org/learn/overview/#integration-with-c-libra...

- https://ziglang.org/documentation/master/#Import-from-C-Head...

Re: Zig 0.8.0 Release Notes

#59
post #28

As the military aphorism go "Amateurs talk strategy. Professionals talk logistics." I like that Zig seems to talk about compiler/linker logistics in great details as opposed to just endless list of new language features and APIs that so many languages do.

(tangent) Huh, I wonder how well that ahorism maps to Linus Torvalds' code/data structures quote: > git actually has a simple design, with stable and reasonably well-documented data structures. In fact, I'm a huge proponent of designing your code around the data, rather than the other way around, and I think it's one of the reasons git has been fairly successful […] I will, in fact, claim that the difference between…

I love that quote from Linus.

In fact, we had it in mind when we designed TigerBeetle [1][2], a financial accounting database to do a million financial transactions a second.

We started with the data structures, made sure that these were one or two cache lines to reduce cache misses and perfectly aligned to eliminate false sharing, and then we added built-in accounting primitives to move the code to the data, instead of the data back and forth across the network to the code, which is how these kinds of balance tracking systems that we were working with before were typically implemented.

The result is much simpler, a perfect replicated state machine, and also much safer, because the business logic and data are executed within the state machine, protected by the distributed consensus protocol (Viewstamped Replication Revisited by Liskov and Cowling), rather than a mess of SQL transactions spanning multiple distributed systems, all with different clocks.

[1] https://github.com/coilhq/tigerbeetle

[2] Guess what language we wrote it in? And this is making more and more sense, like a secret weapon. The community is amazing, deeply talented, with great taste, and at the vanguard of where things are going for these kinds of systems.

Re: Zig 0.8.0 Release Notes

#60
post #43

Earlier quoted context omitted.

> The only code you can be completely certain is correct is the code you didn't have to write. Not true at all, there are always compiler errors, and in many cases you can statically check your code using an external validation system. I'd be 99.999% confident of most of the WRITTEN code of SEL-4, probably more confident than ANY code "not written" in rust, because it's been formally verified by a theorem-proving ext…

Anybody who cannot tell whether a type has a destructor is qualified neither to code nor to audit cryptographic primitives. In any case, cryptographic timing behavior is verified by careful white-box testing, not just inspection. Any bonus destructor activity (if, e.g., somebody unqualified coded it) would show up then. When your case is so weak, it is better not to present it.

"doing almost everything right to become essential infrastructure, but will need to add some equivalent of destructors to get there."

To be fair, if we come back to this opening argument, I'm still wondering how strong the premise here is? Are destructors in fact essential to essential infrastructure as you claim in your view? I'm not sure that I'm convinced by the case as you've presented it so far. I don't think we need to look too far to find counter-examples of essential infrastructure with the highest levels of safety that achieve this safety without destructors, and where destructors would be precluded by the safety model.

Also, as someone who's done a fair amount of security work, the timing safe argument against hidden control flow is at least compelling and something to explore and not ignore out of hand. If a language design can make crypto simpler and safer to implement correctly, then I would say that's already a good indication of what the language may be able to do for less complex domains.

Post reply on HN