惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Help Net Security
G
Google Developers Blog
aimingoo的专栏
aimingoo的专栏
博客园 - 聂微东
酷 壳 – CoolShell
酷 壳 – CoolShell
小众软件
小众软件
Stack Overflow Blog
Stack Overflow Blog
美团技术团队
博客园_首页
T
Tailwind CSS Blog
博客园 - 三生石上(FineUI控件)
B
Blog
D
DataBreaches.Net
腾讯CDC
C
Check Point Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
U
Unit 42
月光博客
月光博客
V
V2EX
Vercel News
Vercel News
T
The Blog of Author Tim Ferriss
The Cloudflare Blog
博客园 - 叶小钗
Y
Y Combinator Blog

HN's home page

Rainbow Query Language | Hacker News Exec into Node via Kubectl An AI native hedge fund The Seven-Action Documentation Model | Hacker News Package Manager for Kubectl Plugins Tongan Castaways | Hacker News Tech overlords plan for conscious AI to conquer the cosmos. What could go wrong? Data Breach Disclosure Lag Is Getting Worse How LLMs Work | Hacker News I Dropped PRDs for Shape Up Go Experiments Explained | Hacker News FCA's Palantir deal could expose UK financial data to Trump's US, critics fear WebXR BCI for Neural-Adaptive Avatar Control in Mixed Reality The first murder conviction via DNA analysis Tom Interviews Theo de Raadt of the OpenBSD Project (2019) [video] Show HN: Replace shell commands with bun shell typescript scripts Quay.io Is Down | Hacker News AI driven analysis of brokerage account fees in the UK Bill Gates Spent Years Crafting His Image. Now It's Cracking Using LLMs to secure source code Wi-Fi 8 in the Lab [video] The household battery revolution that could change energy bills and the world Is Python Becoming Pinyin? | Hacker News Livia – Executive Assistant | Hacker News FindMyPipe – Query Apple Find My from Linux for AI Agents Show HN: Agent skill for creating product launch videos with Remotion RecruitMyself – AI job search copilot for resumes and applications AI coding agents and the erosion of system understanding The 'Resting' Generation and South Korea's Youth Recession AMD Computex 2026: 10 Years of AM4, AM5 Support Through 2029
Asserts in Zig | Hacker News
signa11 · 2026-06-01 · via HN's home page
Asserts in Zig (kristoff.it)
60 points by signa11 5 days ago | hide | past | favorite | 17 comments
 help


Tying asserts to optimization is bad design. Asserts are for debugging; you write an assert when you are not 100% confident that it holds, or there is a risk of it not holding in the future even if it holds now.

The "assert" word is not a great choice, but it's entrenched that way. In a debate, you'd not want to assert something (present it as a fact) if you're not sure.

Optimization promises have the same form; they are also assertions, but with a different purpose. They can use the same syntax, but some different word.

The word assert is attractive for this purpose: I know for sure something is true, and I'm communicating it to the compiler; thus, I am asserting something.

The designer must not be thereby seduced into conflating debugging assertions with optimization promises.

I understand that in this case they have a safety switch for assertions, but conflating debug assertions with optimization promises by means of a switch is still a poor design.

You want that switch on a case-by-case basis for each individual assertion, and the easiest way for that is to just have a different identifier.


I recently worked for a company with a large C++ codebase. For many years they relied entirely on asserts in QA builds to catch errors, no unit testing or production asserts. When I joined about three years ago they had just started to pick up unit testing, and would be enabling asserts in production “soon” (once all the most common ones had been fixed).

I left a little over a month ago, and the status on that was still “soon”. Some bad practices early on are just really hard to dig yourself out of.


I believe this is just about the behavior of std.debug.assert.

You can pretty easily have a different kind of assert that disappears in release builds (if you want).


It's in the article.

> you can implement your own version that internally checks a build-time flag, approximating C/C++ behavior


I really like the Oracle tutorial on Java asserts.

https://docs.oracle.com/javase/8/docs/technotes/guides/langu...

And I'm pretty happy with its design considering its age.

Notably this is not a function call and indeed things are not called unless you enable it. Contrast with Zig. So I guess you will only suffer from code bloat if you never enable them.

The tutorial mentions the dangers of side effects. But it also mentions how to use them for more complicated assertions. That's natural since you'll want something like that when you need to check a post-condition.

Programming assertions get joked on because of, ahem.

- Step one: Turn on extra checks in test environments where the stakes are low

- Step two: Turn them off in production (with realistic data because prod eq. reality) to save cycles

And that seems to be partially accurate. However the truly interesting assertions can test complex conditions that might break complexity (Big O) contracts. Like a private mininum function that is advertised as O(1) on account of taking a sorted list. But there is no type guarantee that the list is sorted. So you assert that it is sorted. But that breaks the complexity contract.

Overall I have not used assertions in Java for trivial conditions in like five years. They're better deployd for something more complex than that.

Then there is the whole thing about -- and more topics to be sure -- crashing the whole application or not. That's not necessarily great for us regular Java programmers. However we can (though discoraged) catch AssertionError if we want to.


"And I'm pretty happy with its design considering its age."

Java did the right thing for assertions but then completely failed for the analoguous issue when it comes to logging.

I admit that logging is more complex because you often want it configurable dynamically at runtime. But I'd argue that the language should not be in your way if all you need is a compile time decision and the contortions we made for logging to stay low cost when nothing is logged are crazy in Java.


If you want, you can actually use assert for conditional logging (and other conditional program logic).


Few Java programmers are using assertions, the two most important reasons being that it’s difficult to reliably ensure they are enabled in production, and secondly that an Error tends to be too disruptive. Instead, most programmers use always-on defensive checks like requireNonNull() that throw RuntimeExceptions.


Asserts in my Rust code use a custom runtime macro "assert_eq_as_result" which does what the article is describing, by returning Rust Ok or Rust Error.

The Rust crate: https://crates.io/crates/assertables

All the macros have forms for different outcomes:

    assert_gt!(1, 2) // panic
    assert_gt_as_result!(1, 2) return Result (Ok or Error)
    debug_assert_gt!(a, b) // panic when running in debug mode

If anyone here wants to help me port it to Zig, I'm happy to do it.


As a contrast to Zig: C3 is strongly invested in contracts and is able to use them for static analysis at compile time to some degree.


There's more to design-by-contract than asserts, and DbC isn't the only way to use asserts. Most languages lack proper support for design-by-contract.

(For what it's worth I didn't downvote you.)


DbC is the Policy (i.e. what/why) and Asserts are the Mechanism (i.e. how) (https://en.wikipedia.org/wiki/Separation_of_mechanism_and_po...) DbC can be implemented in any language that provides an assert-like mechanism (whether named "assert" or not). An Assert merely validates the state of a program at a particular point during execution. You use it to steer the program to go through only the correct subset of the state space of the program. You could do this pre/post every executable statement (i.e. write proof of correctness) or use a higher-level structured methodology like DbC which is far more practical. The given resources address both.

The point is that when using asserts you think about correctness w.r.t. specifications and nothing else. To think of it as simply validating arguments or in terms of effects on optimization is quite the wrong thing to do.

PS: I don't bother about upvotes/downvotes but am often reminded of the following Sherlock Holmes quote when i see HN's reaction to deeper subjects ;-)

Pshaw, my dear fellow, what do the public, the great unobservant public, who could hardly tell a weaver by his tooth or a compositor by his left thumb, care about the finer shades of analysis and deduction!"


> DbC is the Policy (i.e. what/why) and Asserts are the Mechanism

The ideal way to do runtime-checked DbC is not with simple asserts, it's with proper first-class preconditions and postconditions at the language level.

It wouldn't be nice to have to manually ensure that both old and new states of variables are in-scope for postcondition checking. I can imagine that being not just tedious, but error-prone.

> An Assert merely validates the state of a program at a particular point during execution.

Some aspect of the program's state, yes, and hopefully that's all it does.

Interesting to think about the edge-cases here though. Depending on the language, it could accidentally side-effect, or even invoke undefined behaviour, and so actively derail the program. Can't blame DbC for that though, that's a question of language safety.

> You use it to steer the program to go through only the correct subset of the state space of the program

I'm not sure I follow here. You don't use asserts to steer flow-control, you use them to check aspects of program state.

> You could do this pre/post every executable statement (i.e. write proof of correctness)

That doesn't constitute a proof of correctness, no more than last time you and I discussed this. [0] Depending on the language, it wouldn't even necessarily prove the correctness of that particular trace, as you haven't proven that you haven't accidentally invoked undefined behaviour.

You hold a minority opinion on this, please stop presenting it as settled fact.

> The point is that when using asserts you think about correctness w.r.t. specifications and nothing else. To think of it as simply validating arguments or in terms of effects on optimization is quite the wrong thing to do.

I'm not sure why you'd think I don't already know that.

[0] https://news.ycombinator.com/item?id=44675668


Very interesting write-up, thank you! I never really considered that compilers can also use asserts to improve performance, but it does make sense.


> Imagine a big codebase with this somewhere in it:

    fn processThing(thing: Thing) void {
       // this function must always be invoked on
       // a thing that has already been started
       assert(thing.is_started);
   
       // ...
    }

I know you mentioned fuzzing earlier in the article but seriously, fuzzing deserves an extra mention after asking me to imagine that.