Type resolution redesign, with language changes to taste (ziglang.org)

mlugg 22 hours ago

Hi, author of this devlog here! Not to dismiss concerns about breaking language changes, but there seems to be a bit of a misconception here that this compiler change was highly breaking and will require significant effort from Zig users to update for. Perhaps I unintentionally gave that impression in the devlog or the PR writeup, apologies if so---but it's not the case! Although there were breaking changes in this patch, they were quite minor: most users are unlikely to hit them, and if they do then they're straightforward to deal with.

For a concrete example, while testing this branch, I tried building ZLS (https://github.com/zigtools/zls/). To do that, the only change I had to make was changing `.{}` to `.empty` in a couple of its dependencies (i.e. not even in ZLS itself!). This was needed because I removed some default values from `std.ArrayList` (so the change was in standard library code rather than the language). Those default values had actually already been deprecated (with intent to remove) for around a year, so this wasn't exactly a new change either.

As another example, Andrew has updated Awebo (https://codeberg.org/awebo-chat/awebo), a text and voice chat application, to the new version of Zig. Across Awebo's entire dependency tree (which includes various packages for graphics, audio, and probably some other stuff), the full set of necessary changes was:

* Same as above, change `.{}` to `.empty` in a few places, due to removal of deprecated defaults

* Add one extra `comptime` annotation to logic which was constructing an array at comptime

* Append `orelse @alignOf(T)` onto an expression to deal with a newly-possible `null` case

These are all trivial fixes which Zig developers would be able to do pretty much on autopilot upon seeing the compile errors.

So, while there were a handful of small breaking changes, they don't seem to me like a particularly big deal (for a language where some level of breakage is still allowed). The main thing this PR achieved was instead a combination of bugfixes, and enhancements to existing features (particularly incremental compilation).

throwaway17_17 22 hours ago

I made one of the comments that seems to be perceived a critical of the changes (I made a statement about the seemingly brief paragraph on changing semantics). As I replied to Andrew, I will tell you: the PR had a large amount of planning and implementation that seems of great quality. I certainly did not intend to discredit you or the obviously large amount of work you have done previously or on the change. I guess that will teach me to post without even more caveats.

mlugg 21 hours ago

Oh, no problem at all & no shade of any kind intended! I just wanted to clarify this point since it seems like a good few people got that misconception. That doesn't mean you can't discuss breakage anyway, or ask questions of the development / language design process :)

kristoff_it 21 hours ago

Your comment was reasonable, I don't know why it got downvoted that hard.

skavi 21 hours ago

I am going to ask a question that is is definitely not the place for, but I am not involved with Zig in any way and am curious, so I hope you'll indulge me.

I noticed the following comment was added to lib/std/multi_array_list.zig [0] with this change:

        /// This pointer is always aligned to the boundary `sizes.big_align`; this is not specified
        /// in the type to avoid `MultiArrayList(T)` depending on the alignment of `T` because this
        /// can lead to dependency loops. See `allocatedBytes` which `@alignCast`s this pointer to
        /// the correct type.
How could relying on `@alignOf(T)` in the definition of `MultiArrayList(T)` cause a loop? Even with `T` itself being a MultiArrayList, surely that is a fully distinct, monomorphized type? I expect I am missing something obvious.

[0]: https://codeberg.org/ziglang/zig/pulls/31403/files#diff-a6fc...

messe 17 hours ago

I had to search for this, but managed to find the relevant mlugg@ comment[0] on the ZSF zulip:

> i had to change the bytes field from [*]align(@alignOf(T)) u8 to just [*]u8 (and cast the alignment back in the like one place that field is accessed). this wasn't necessary for MultiArrayList in and of itself, but it was necessary for embedding a MultiArrayList(T) inside of T without a dependency loop, like

    const T = struct {
        children: MultiArrayList(T),
    };
    // reproduced for completeness:
    fn MultiArrayList(comptime T: type) type {
        return struct {
            bytes: [*]align(@alignOf(T)) u8,
            // ...
        };
    }
[0]: https://zsf.zulipchat.com/#narrow/channel/454360-compiler/to...
skavi 15 hours ago

Ah, that makes sense. Thanks for pulling this up!

messe 14 hours ago

He went into it a bit more over on Ziggit today too. I only noticed it way after I went digging: https://ziggit.dev/t/devlog-type-resolution-redesign-with-la...

h4ch1 1 day ago

I would really like to hear from people using Zig in production/semi-serious applications; where software stability is important.

How's your experience with the constantly changing language? How're your update/rewrite cycles looking like? Are there cases where packages you may use fall behind the language?

I know Bun's using zig to a degree of success, was wondering how the rest were doing.

rtfeldman 1 day ago

I maintain a ~250K LoC Zig compiler code base [0]. We've been through several breaking Zig releases (although the code base was much smaller for most of that time; Writergate is the main one we've had to deal with since the code base crossed the 100K LoC mark).

The language and stdlib changing hasn't been a major pain point in at least a year or two. There was some upgrade a couple of years ago that took us awhile to land (I think it might have been 0.12 -> 0.13 but I could be misremembering the exact version) but it's been smooth sailing for a long time now.

These days I'd put breaking releases in the "minor nuisance" category, and when people ask what I've liked and disliked about using Zig I rarely even remember to bring it up.

[0]: https://github.com/roc-lang/roc

sureglymop 23 hours ago

At this point do you believe porting the codebase to Zig was the right decision? Do you have any regrets?

Also, I'm excited about trying out your language even moreso than Zig. :)

wvlia5 21 hours ago

What's the main value proposition of roc? I found interesting tags (like symbols in mathematica) and tags with payloads (like python namedtuple or dataclasses). I haven't seen this elsewhere. Otherwise seems quite typical (Pattern matching is quite common, for example).

Example programs that you couldn't easily express in other languages?

rkangel 18 hours ago

Are you aware that your Github README doesn't actually tell us anything about Roc is or why we might be interested?

This might be on purpose given the first words are "Work in progress" and "not ready for release", but linking as above does lose some value.

messe 17 hours ago

Instead of being rude, consider checking Roc's website: https://roc-lang.org/

He wasn't pitching the language directly, but linking to the codebase as that was what was relevant to the comment he was replying to.

rkangel 16 hours ago

If I missed with tone, that's on me. I was going for "helpful constructive feedback".

kprotty 1 day ago

I've worked on two "production" zig codebases: tigerbeetle [0] and sig [1].

These larger zig projects will stick to a tagged release (which doesn't change), and upgrade to newly tagged releases, usually a few days or months after they come out. The upgrade itself takes like a week, depending on the amount of changes to be done. These projects also tend to not use other zig dependencies.

[0]: https://github.com/tigerbeetle/tigerbeetle/pulls?q=is%3Apr+a...

[1]: https://github.com/Syndica/sig/pulls?q=is%3Apr+author%3Akpro...

ryanxsim 1 day ago

I really wanted to deep dive into zig but I'm into rust now kinda late as I'm really just started like 2024.

Have you tried rust? how does it compared to zig?

* just asking

weebull 1 day ago

Two different philosophical approaches with Zig and Rust.

- Zig: Let's have a simple language with as few footguns as possible and make good code easy to write. However we value explicitness and allow the developer to do anything they need to do. C interoperability is a primary feature that is always available. We have run time checks for as many areas of undetermined behaviour as we can.

- Rust: let's make the compiler the guardian of what is safe to do. Unless the developer hits the escape hatch, we will disallow behaviour to keep the developer safe. To allow the compiler to reason about safety we will have an intricate type system which will contain concepts like lifetimes and data mobility. This will get complex sometimes so we will have a macro system to hide that complexity.

Zig is a lot simpler than Rust, but I think it asks more of it's developer.

lerno 23 hours ago

> However we value explicitness and allow the developer to do anything they need to do*

* except for having unused variables. Those are so dangerous the compiler will refuse the code every time.

rllj 22 hours ago

They are indeed dangerous, and I think this is a pretty good example of why.

https://andrewkelley.me/post/openzfs-bug-ported-zig.html

dnautics 17 hours ago

don't know if it's still on the table, but Andrew has hinted that the unused variables error may in the future still produce an executable artefact but return an nonzero return code for the compiler. And truly fatal errors would STILL produce an executable artefact too, just one that prints "sorry this compilation had a fatal error" to stdout.

nulltype 22 hours ago

It’s hard to say that one needs unused variables.

duped 21 hours ago

If I comment out sections of code while debugging or iterating I don't want a compile error for some unused variable or argument. Warning. fine, but this happens to me so frequently that the idea of unused variables being an error is insane to me.

CyberDildonics 18 hours ago

It is insane and you are completely right. This has been a part of programming for over 50 years. Unfortunately you aren't going to get anywhere with zig zealots, they just get mad when confronted with things like this that have no justification, but they don't want to admit it's a mistake.

gf000 16 hours ago

But even the solutions would be so trivial - have a separate 'prod' compiler flag. With that, make these errors, without make these warnings.

Problem solved, everyone happy.

CyberDildonics 15 hours ago

You are right of course, the solution is trivial.

They also made a carriage return crash the compiler so it wouldn't work with any default text files on windows, then they blamed the users for using windows (and their windows version of the compiler!).

It's not exactly logic land, there is a lot of dogma and ideology instead of pragmatism.

Some people would even reply how they were glad it made life difficult for windows users. I don't think they had an answer for why there was a windows version in the first place.

thezipcreator 6 hours ago

I'm not sure why you shouldn't make your compiler accept CRs (weird design decision), but fixing it on the user-side isn't exactly hard either. I don't know an editor that doesn't have an option for using LF vs CRLF.

The unused variable warning is legitimately really annoying though and has me inserting `_ = x;` all over the place and then forgetting to delete it, which is imo way worse than just... having it be a warning.

gabriela_c 21 hours ago

Same for kernel drivers

Ygg2 1 day ago

That's disingenous, Rust tries to minimize errors, first at compile time then at runtime, even if it at some discomfort of to programer.

Zig goes for simplicity while removing a few footguns. It's more oriented towards programmer enjoyment. Keep in mind that programmers don't distinguish ease of writing code from ease of writing unforeseen errors.

CyberDildonics 21 hours ago

as few footguns as possible

There are no destructors so all the memory ownership footguns are still there.

thezipcreator 6 hours ago

sure, but when I've written zig this has never been an issue for me. `defer` makes memory management really easy.

If you want to auto-generate destructors, zig has really good comptime features that can let you do that.

xeonmc 1 day ago

Rust is a Bugatti Veyron, Zig is a McLaren F1.

lionkor 1 day ago

Zig is a modern C,

Rust is a modern C++/OCaml

So if you enjoy C++, Rust is for you. If you enjoy C and wish it was more verbose and more modern, try Zig.

mgoetzke 23 hours ago

As someone who never liked writing anything C++ since 2000+ (did like it before) I cannot agree with this. C++ and Rust are not comparable in this sense at all.

One can argue Rust is what C++ wanted to be maybe. But C++ as it is now is anything but clean and clear.

lionkor 22 hours ago

See my other comment[1]

It replaces C++ for me, so I would say it's "a C++"

[1]: https://news.ycombinator.com/item?id=47334275

keybored 21 hours ago

And in a world of only you your claim is true.

naasking 19 hours ago

I think the comparison is fair, strictly in the sense that both Rust and C++ are designed around extensible programming via a sort of subtyping (C++ classes, Rust traits), and similar resource management patterns (ownership, RAII), where Zig and C do not have anything comparable.

microtonal 1 day ago

It is kind of interesting that the Linux kernel is slowly adopting Rust, whereas Zig seems like it would be a more natural fit?

I know, timelines not matching up, etc.

nasretdinov 1 day ago

Memory safety by default in kernel sounds like a good idea :). However I don't think that C is being _replaced_ by Rust code, it's rather that more independent parts that don't need to deeply integrate with the existing C constructs can be written in a memory safe language, and IMO that's a fine tradeoff

smj-edison 21 hours ago

I believe Rust is mainly being used for driver development, which seems a great fit (there's so many people of different skill levels who write Linux drivers, so this should help avoid bad driver code being exploited). It may also end up in the core systems, but it also might not fit there as well.

andrepd 1 day ago

Definitely not. Rust gives you a tangible benefit in terms of correctness. It's such a valuable benefit that it outweighs the burden of incorporating a new language in the kernel, with all that comes with it.

Zig offers no such thing. It would be a like-for-like replacement of an unsafe old language with an unsafe new one. May even be a better language, but that's not enough reason to overcome the burden.

dnautics 22 hours ago

actually that's not true at all. Zig offers you some more safety than C. And it also affords you a compiler architecture and stdlib that is so well designed you could probably bolt on memory safety relatively easily as a 3rd party static checker

https://github.com/ityonemo/clr

simonask 22 hours ago

"More safety than C" is an incredibly low bar. These are hygiene features, which is great, but Rust offers a paradigm shift. It's an entirely different ballpark.

dnautics 20 hours ago

negative. For example bounds checking is turned on by default in Zig, which prevents classes of overflow safety errors.

simonask 3 hours ago

I don't think you've necessarily understood the scope and impact of the borrow checker. Bounds checking is just a sane default (hygiene), not a game changer.

keybored 1 day ago

And “if you enjoy C++/if you enjoy C” are gross oversimplifications.

lionkor 21 hours ago

And Zig isn't stable yet

geon 1 day ago

Comparing Rust to C++ feels strange to me.

It’s like people do it just because Zig is very comparable to C. So the more complex Rust must be like something else that is also complex, right? And C++ is complex, so…

But that is a bit nonsensical. Rust isn’t very close to C++ at all.

lionkor 23 hours ago

I wrote lots of C++ before learning Rust, and I enjoyed it. Since learning Rust, I write no more C++. I found no place in which C++ is a better fit than Rust, and so it's my "new C++".

For example, high performance servers (voltlane.net), programming languages (https://github.com/HF-Foundation, https://github.com/lionkor/mcl-rs, and one private one), webservers (beampaint.com) and lots of other domains.

Rust is close to C++ in that it is a systems language that allows a reasonable level of zero-cost abstractions.

pjmlp 22 hours ago

> found no place in which C++ is a better fit than Rust, and so it's my "new C++".

Writing the compiler toolchains that Rust depends on, industry standards like CUDA, SYSCL, Metal, Unreal or the VFX Reference Platform.

kprotty 21 hours ago

There are places a language could be a better fit, but which haven't adopted it. E.g. most languages over typescript on the backend, most systems programming languages over Java for games.

pjmlp 20 hours ago

The fallacy is to discuss programming languages in isolation without taking the whole ecosystem into consideration.

simonask 22 hours ago

Rust uses LLVM because it's pretty great, not because you couldn't implement LLVM in Rust.

Maybe cranelift will eventually surpass LLVM, but there isn't currently much reason to push for that.

estebank 20 hours ago

If anything, making cranelift an LLVM replacement would likely go counter to its stated goals of being a simple and fast code generator.

pjmlp 20 hours ago

Thus Rust cannot really replace C++ when its reference toolchain depends on it.

estebank 19 hours ago

If you define success for Rust as "everything is written in Rust", then Rust will never be successful. The project also doesn't pursue success in those terms, so it is like complaining about how bad a salmon is at climbing trees.

pjmlp 15 hours ago

That is however how the Rust Evangelism Strike Force does it all the time, hence these kind of remarks I tend to do.

C++ is good for some things regardless of its warts due to ecosystem, and Rust is better in some other ones, like being much safer by default.

Both will have to coexist in decades to come, but we have this culture that doesn't accept matches that end in a draw, it is all about being in the right tribe.

simonask 3 hours ago

So... Like, what? Do you agree that there is no technical reason for LLVM to be written in C++ over Rust?

Have you considered that you perhaps do more damage to the conversation by having it with this hypothetical strike force instead of the people that are actually involved in the conversation? Whose feelings are you trying to protect? What hypocrisy are you trying to expose? Is the strike force with us in the room right now?

pjmlp 3 hours ago

I assert there is no reason to rewrite LLVM in Rust.

And I also assert that the speech that Rust is going to take over the C++, misses on that as long as Rust depends on LLVM for its existence.

Or ignoring that for the time being NVidia, Intel, AMD, XBox, PlayStation, Nintendo, CERN, Argonne National Laboratory and similar, hardly bother with Rust based software for what they do day to day.

They have employees on WG14, WG21, contribute to GCC/clang upstream, and so far have shown no interest in having Rust around on their SDKs or research papers.

NaN years ago

undefined

jodleif 23 hours ago

I found swift way more enjoyable than rust as a C++ alternative. It even has first class-ish interop now.

bayindirh 1 day ago

Seriously asking, where Go sits in this categorization?

gf000 1 day ago

Nowhere, or wherever C# would sit. Go is a high level managed language.

andrewl-hn 1 day ago

Go is modern Java, at least based on the main area of usage: server infrastructure and backend services.

KronisLV 1 day ago

Tbh Go is also really nice for various local tools where you don’t want something as complex as C++ but also don’t want to depend on the full C# runtime (or large bundles when self-contained), or the same with Java.

With Wails it’s also a low friction way to build desktop software (using the heretical web tech that people often reach for, even for this use case), though there are a few GUI frameworks as well.

Either way, self contained executables that are easy to make and during development give you a rich standard library and not too hard of a language to use go a long way!

bsaul 1 day ago

i wonder what makes go more modern than java, in terms of features.

cultab 1 day ago

The tooling and dependency management probably

thezipcreator 6 hours ago

I still don't understand how they managed to make a build system as bad as Gradle. It's like they tried to make it as horrible as possible to use.

kristianp 4 hours ago

Yes, every time I fire up an old Android project it needs to download 500MB just for gradle upgrades. It's nuts.

9rx 18 hours ago

Go is modern/faster Python.

- It was explicitly intended to "feel dynamically-typed"

- Tries to live by the zen of Python (more than Python itself!)

- Was built during the time it was fashionable to use Python for the kinds of systems it was designed for, with Google thinking at the time that they would benefit from moving their C++ systems to that model if they could avoid incurring the performance problems associated with Python. Guido Van Rossum was also employed at Google during this time. They were invested in that sort of direction.

- Often reads just like Python (when one hasn't gone deep down the rabbit hole of all the crazy Python features)

shilgapira 1 day ago

It's also a modern C.

If you enjoy C and wish it was less verbose and more modern, try Go.

VorpalWay 1 day ago

Go has a garbage collector though. This makes it unsuitable for many use cases where you could have used C or C++ in the past. Rust and Zig don't have a GC, so they are able to fill this role.

GC is a showstopper for my day job (hard realtime industrial machine control/robotics), but would also be unwanted for other use cases where worst case latency is important, such as realtime audio/video processing, games (where you don't want stutter, remember Minecraft in Java?), servers where tail latency matters a lot, etc.

bboozzoo 23 hours ago

> GC is a showstopper for my day job (hard realtime industrial machine control/robotics)

Which is a very niche use case to begin with, isn't it? It doesn't really contradict what the parent comment stated about Go feeling like modern C (with a boehm gc included if you will). We're using it this way and it feels just fine. I'd be happy to see parts of our C codebase rewritten in Go, but since that code is security sensitive and has already been through a number of security reviews there's little motivation to do so.

VorpalWay 23 hours ago

> Which is a very niche use case to begin with, isn't it?

My specific use case is yes, but there are a ton of microcontrollers running realtime tasks all around us: brakes in cars, washing machine controllers, PID loops to regulate fans in your computer, ...

Embedded systems in general are far more common than "normal" computers, and many of them have varying levels of realtime requirements. Don't believe me? Every classical computer or phone will contain multiple microcontrollers, such as an SSD controller, a fan controller, wifi module, cellular baseband processor, ethernet NIC, etc. Depending on the exact specs of your device of course. Each SOC, CPU or GPU will contain multiple hidden helper cores that effectively run as embedded systems (Intel ME, AMD PSP, thermal management, and more). Add to that all the appliances, cars, toys, IOT things, smartcards, etc all around us.

No, I don't think it is niche. Fewer people may work on these, but they run in far more places.

pjmlp 22 hours ago

See TamaGo, used to write firmware in Go, being shipped in production.

VorpalWay 22 hours ago

Not familiar with it, but reading the github page it isn't clear how it deals with GC. Do you happen to know?

Some embedded use cases would be fine with a GC (MicroPython is also a thing after all). Some want deterministic deallocation. Some want no dynamic allocator at all. From what I have seen, far more products are in the latter two categories. While many hobby projects fall into the first two categories. That is of course a broad generalization, but there is some truth to it.

Many products want to avoid allocation entirely either because of the realtime properties, or because they are cost sensitive and it is worth spending a little bit extra dev effort to be able to save an Euro or two and use a cheaper microcontroller where the allocator overhead won't fit (either the code in flash, or just the bookkeeping in RAM).

pjmlp 20 hours ago

Yes, just like with real time Java for embedded targets from PTC and Aicas, it is its own implementation with another GC algorithm, additionally there are runtime APIs for regions/arenas.

Here is the commercial product for which it was designed,

https://reversec.com/usb-armory

A presentation from 2024,

https://www.osfc.io/2024/talks/tamago-bare-metal-go-for-arm-...

simonask 22 hours ago

Not everybody is writing web apps.

You can also see it differently: If the language dictates a 4x increase in memory or CPU usage, you have set a much closer deadline before you need to upgrade the machine or rearchitect your code to become a distributed system by a factor 4 as well.

Previously, delivering a system (likely in C++) that consumed factor 4 fewer resources was an effort that cost developer time at a much higher factor, especially if you had uptime requirements. With Rust and similar low-overhead languages, the ratio changes drastically. It is much cheaper to deliver high-performance solutions that scale to the full capabilities of the hardware.

bayindirh 1 day ago

Thanks. I write some Go, and feel the same about it. I really enjoy it actually.

Maybe I'll jump to Zig as a side-gig (ha, it rhymes), but I still can't motivate myself to play with Rust. I'm happy with C++ on that regard.

Maybe gccrs will change that, IDK, yet.

Imustaskforhelp 16 hours ago

Go is a language which sits perfectly where using garbage collection is no problem with ya.

api 1 day ago

My take, unfortunately, is that Zig might be a more modern C but that gives us little we don’t already have.

Rust gives us memory safety by default and some awesome ML-ish type system features among other things, which are things we didn’t already have. Memory safety and almost totally automatic memory management with no runtime are big things too.

Go, meanwhile, is like a cleaner more modern Java with less baggage. You might also compare it to Python, but compiled.

kprotty 21 hours ago

Zig gives things we really dont have yet: C + generics + good const eval + good build system + easy cross compilation + modern niceties (optionals, errors, sum types, slices, vectors, arbitrary bit packing, expression freedom).

Are there any other languages that provide this? Would genuinely consider the switch for some stuff if so.

pjmlp 22 hours ago

Zig is Modula-2/Object Pascal re-packaged with a C like syntax.

7bit 1 day ago

C++ added OOP to C.

Rust is not object-oriented.

That makes your statement wrong.

pjmlp 22 hours ago

It certainly is according to the various CS definitions of type systems.

Plenty of OOP architectures can be implemented 1:1 in Rust type system.

9rx 18 hours ago

Yes, of course you can call objc_msgSend or equivalent in Rust just as you can in C. But you are pushing the object-oriented model into a library. It is not native to the language.

pjmlp 15 hours ago

I am talking about Rust OOP language features for polymorphism, dynamic and static dispatch, encapsulation, interfaces.

Which allowed me to port 1:1 the Raytracing Weekend tutorial from the original OOP design in C++ to Rust.

Also the OOP model used by COM and WinRT ABIs, that Microsoft makes heavy use of in their Rust integration across various Windows and Office components.

Ygg2 22 hours ago

> Plenty of OOP architectures can be implemented 1:1

Plenty of OOP architecture can be implemented in C. That's an extremely flawed and fuzzy definition. But we've been through this before.

pjmlp 20 hours ago

Yet people have to keep be reminded of it.

Ygg2 17 hours ago

I think the issue is OOP patterns are one part missing features, one part trying to find common ground for Java, Modula, C++, SmallTalk, that it ends up too broad.

A much saner definition is looking at how languages evolved and how term is used. The way it's used is to describe an inheritance based language. Basically C++ and the descendants.

9rx 16 hours ago

> one part trying to find common ground for Java, Modula, C++

The primary common ground is that their functions have encapsulation, which is what separates it from functions without encapsulation (i.e. imperative programming). This already has a name: Functional programming.

The issue is that functional, immutable programming language proponents don't like to admit that immutability is not on the same plane as imperative/functional/object-oriented programming. Of course, imperative, functional, and object-oriented language can all be either mutable or immutable, but that seems to evade some.

> SmallTalk

Smalltalk is different. It doesn't use function calling. It uses message passing. This is what object-oriented was originally intended to reference — it not being functional or imperative. In other words, "object-oriented" was coined for Smalltalk, and Smalltalk alone, because of its unique approach — something that really only Objective-C and Ruby have since adopted in a similar way. If you go back and read the original "object-oriented" definition, you'll soon notice it is basically just a Smalltalk laundry list.

> how term is used.

Language evolves, certainly. It is fine for "object-oriented" to mean something else today. The only trouble is that it's not clear to many what to call what was originally known as "object-oriented", etc. That's how we end up in this "no its this", "no its that" nonsense. So, the only question is: What can we agree to call these things that seemly have no name?

9rx 19 hours ago

Objective-C added OOP to C. C++ did not. C++ is neither an OO language nor a C superset.

CyberDildonics 13 hours ago

If you make up your own definitions things can be anything you want and have or not have any label.

9rx 11 hours ago

Absolutely. That's why it is best to stick to the already established definitions. Kay was quite explicit about what "object-oriented" meant when the term was uttered for the first time; including specifically calling out C++ as not being object-oriented.

And yes, we all know the rest of the story about how the C++ guys were butthurt by that callout and have been on a mission to make up their own pet definition that allows C++ to become "object-oriented" ever since. I mean, who wouldn't want to latch onto a term that was about the unique features of a failed programming language that never went anywhere?

benob 1 day ago

Time to start zig++

kprotty 22 hours ago

Yes, I've written a few unsafe-focused crates [0], some of which have been modified & merged into the stdlib [1] [2] exposing them to the fringe edge-cases of Rust like strict provenance.

IMO, Rust is good for modeling static constraints - ideal when there's multiple teams of varying skill trying to work on the same codebase, as the contracts for components are a lot clearer. Zig is good for expressing system-level constructs efficiently: doing stuff like self-referential/intrusive data structures, cross-platform simd, and memory transformations is a lot easier in Zig than Rust.

Personally, I like Zig more.

[0] https://crates.io/users/kprotty

[1] https://github.com/rust-lang/rust/pull/95801

[2] https://github.com/rust-lang/rust/blob/a63150b9cb14896fc22f9...

nindalf 20 hours ago

Zig is what you want to write, because it gets out of the way.

Rust is what you want your colleagues to write, to enforce good practices and minimise bugs. It's also what I want my past self to have written, because that guy is always doing things that make my present life harder.

dnautics 15 hours ago

zig really makes it unappealing to architecture astronaut, and rust pushes you towards it. id rather my colleagues write zig

9rx 19 hours ago

I'd rather my colleagues (and past self) write Rocq.

Rust is what you use when you'd rather spend time doing sales and marketing for Rust than building software.

latch 1 day ago

Zig 0.15 is pretty stable. The biggest issue I face daily are silent compiler errors (SIGBUS) for trivial things, e.g. a typo in an import path. I've yet to find exactly why this [only sometimes] causes such a crash, but they're a real pain to figure out over a large changeset. `zig ast-check` sometimes catches the error, else Claude's pretty good at spotting where I accidentally re-used a variable name (again, 90% of the time I do that, it's an easy error, but the other 10%, I get a message-less compiler crash). It sounds like the changes in the OP might be specifically addressing these types of issues.

Also, my .zig-cache is currently at 173GB, which causes some issues on the small Linux ARM VPS I test with.

As for upgrades. I upgraded lightpanda to 0.14 then 0.15 and it was fine. I think for lightpanda, the 0.16 changes might not be too bad, with the only potential issue coming from our use of libcurl and our small websocket server (for CDP connections). Those layers are relatively isolated / abstracted, so I'm hopeful.

As a library developer, I've given up following / tracking 0.16. For one, the change don't resonate with me, and for another, it's changing far too fast. I don't think anyone expects 0.16 support in a library right now. I've gotten PRs for my "dev" branches from a few brave souls and everyone seems happy with that arrangement.

sidkshatriya 1 day ago

> The biggest issue I face daily are silent compiler errors (SIGBUS) for trivial things, e.g. a typo in an import path.

I don't use zig. My experience has been that caches themselves are sources of bugs (not talking about zig only, but in general). Clearing all relevant caches occasionally is useful when you're experiencing weird bugs.

sidkshatriya 1 day ago

I don't know why I was downvoted here. One day, I was experiencing weird compilation errors. Clearing the `ccache` C/C++ compiler cache helped get past the problem. Yes, I could have investigated in detail what was the issue and if ccache had a bug but sometimes you don't have the luxury of investigating everything your toolchain throws at you.

cwillu 22 hours ago

You don't use it, but you're offering unsolicited advice about it, and that advice is very generic.

It's not even an argument that you're wrong, just that it's not contributing much and people think that other replies should come first.

jmull 18 hours ago

Never mind that the previous poster’s insight about caches is correct.

Zig has had caching bugs/issues/limitations that could be worked around by clearing the cache. (Has had, and more that likely still has, and will have.)

quag 1 day ago

That .zig-cache seems massive to me. I keep mine on a tmpfs and remove it every time the tmpfs is full.

Do you see any major problems when you remove your .zig-cache and start over?

latch 1 day ago

Just a slower build. From ~20 seconds to ~65 seconds the first time after I nuke it.

h4ch1 1 day ago

But why is it so big in the first place?

I was searching around for causes and came across the following issues: https://github.com/ziglang/zig/issues/15358 which was moved to https://codeberg.org/ziglang/zig/issues/30193

The following quotes stand out

> zig's caching system is designed explicitly so that garbage collection could happen in one process simultaneously while the cache is being used by another process.

> I just ran WizTree to find out why my disk was full, and the zig cache for one project alone was like 140 GB.

> not only the .zig-cache directory in my projects, but the global zig cache directory which is caching various dependencies: I'm finding each week I have to clear both caches to prevent run-away disk space

Like what's going on? This doesn't seem normal at all. I also read somewhere that zig stores every version of your binary as well? Can you shed some light on why it works like this in zigland?

Cloudef 1 day ago

AFAIK garbage collection is basically not implemented yet. I myself do `ZIG_LOCAL_CACHE_DIR=~/.cache/zig` so I only have to nuke single directory whenever I feel like it.

divan 1 day ago

what exactly people call 'garbage collection' in Zig? build cache cleanup?

Cloudef 1 day ago

Indeed what was referred to here is the zig build system cache.

sgt 1 day ago

Does Zig have incremental builds yet? Or is it 20 secs each time for your build.

latch 1 day ago

20 seconds each time. Last time I tried to enable incremental build, it wasn't working for us. It was a while ago, but I think it had to do with something in our v8 bridge.

sgt 1 day ago

I have heard that from other Zig devs too. Must get a bit annoying as the project grows. But I guess it will be supported sooner or later.

cwillu 22 hours ago

It's discussed in the post.

MrResearcher 5 hours ago

Running a ~20Kloc 0.16 Zig in prod, compiled and deployed as DebugSafe. No issues, superstable. This was rewrite of Node.js/Typescript computation module, and we chose Zig over Rust due to better support for f128. Zig/DebugSafe is approximately twice faster than TypeScript/Node.js 25 for our purpose, with approximately 70% less memory consumption. We were not impacted by WriterGate and other recent scandals much because we primarily rely on libc, and we don't use much of Zig's I/O standard lib.

Zig has a better support for sqlite/JSON serialization (everything is strongly typed and validated) than Node.js, so that was a plus as well.

Zig minuses are well known: lack of syntax sugar for closures/lambdas/vtable, which makes it hard to isolate layers of code for independent development.

We use Arcs (atomic reference counting) with resource scopes (bumper allocators) extensively, so memory safety is not a concern despite aggressively multithreading logic. The default allocator automatically detects memory leaks, use-after-free, etc so we are planning to continue running it in DebugSafe indefinitely. We tried switching to ReleaseFast and gained about 25%, which is not that much faster to lose memory safety guarantees.

nickysielicki 1 day ago

The forever backwards compatible promise of C++ was a tremendous design mistake that has resulted in mindshare death as of 2026. It might suck to have to modify your code to continue to get it to work, but it’s the right long term approach.

wolvesechoes 1 day ago

> that has resulted in mindshare death as of 2026

I could make a bet that as of 2026 still more C++ projects are being started than Rust + Zig combined.

World is much more vast than ShowHN and GitHub would indicate.

mcherm 1 day ago

Being started? I would take that bet.

pjmlp 22 hours ago

It suffices to use the games industry, HFT and HPC as domains.

the_duke 1 day ago

Rust has managed just fine to remain mostly backwards compatible since 1.0 , while still allowing for evolution of the language through editions.

This puts much more work on the compiler development side, but it's a great boon for the ecosystem.

To be fair, zig is pre 1.0, but Zig is also already 8 years old. Rust turned 1.0 at ~ 5 years, I think.

melodyogonna 1 day ago

Rust started in 2006 and reached v1 in 2015, that's 9 years.

kibwen 20 hours ago

Rust existed nearly entirely on paper until 2009, when Mozilla started funding researchers to work on it full-time. It wasn't announced in any sort of official capacity until 2010, and had no official numbered release until 2012. It was less than three and a half years between 0.1 and 1.0, and in that time, hard as it is to believe, it underwent more overall change than Zig has.

fouronnes3 1 day ago

Mindshare death is a very large overstatement given the massive amount of legacy C++ out there that will be maintained by poor souls for year to come. But you are right, there used to be a great language hiding within C++ if the committee ever dared to break backwards compat. But even if they did it now it would be too late and they'd just end up with a worse Rust or Zig.

munificent 1 day ago

The biggest problem with C++ is that while everyone agrees there is a great language hiding in it, everyone also has a remarkably different idea of what that great language actually is.

tialaramex 1 day ago

I don't agree there's a great language hiding in C++. My high level objections would be that the type system is garbage and the syntax is terrible, so you'd need a different type system and syntax and that's nothing close to C++ after the changes.

After many years of insisting that "dialects" of C++ are a terrible idea, despite the reality that most C++ users have a specific dialect they use - Bjarne Stroustrup has endorsed essentially the same thing but as "profiles" to address safety issues. So for people who think there is a "great language" in there perhaps in C++ 29 or C++ 32 you will be able to find out for yourselves that you're wrong.

ChrisGreenHeur 1 day ago

There are multiple great languages hiding within it

pjmlp 1 day ago

As proven a few times, it doesn't matter if committee decides to break something if compiler vendors aren't on board with what is being broken.

There is still this disconnection on how languages under ISO process work in the industry.

jonstewart 1 day ago

The C++ standards committee’s antiquated reliance on compiler “vendors” holds it back. They should adopt maintenance of clang and bless it as the reference compiler.

pjmlp 22 hours ago

And you will be the one telling the losers that their compiler, operating systems and OS doesn't count?

By the way this applies to the C language so beloved on this corner as well.

As it does to COBOL, Fortran, Ada and JS (ECMA is not much different from ISO).

whobre 23 hours ago

The forever backwards compatible promise of C++ is pretty much the main reason anyone is using C++.

pjmlp 1 day ago

There is a reason GCC, LLVM, CUDA, Metal, HPC,.. rely on C++ and will never rewrite to something else, including Zig.

surajrmal 1 day ago

Yes, inertia. If those projects started today, they would likely choose rust.

pjmlp 1 day ago

Why isn't rustc using Cranelift then?

norman784 1 day ago

I can think a few reasons:

- Cranelift applies less optimizations in exchange for faster compilation times, because it was developed to compile WASM (wasmtime), but turns out that is good enough for Rust debug builds.

- Cranelift does not support the wide range of platforms (AFAIK just X86_64 and some ARM targets)

pjmlp 1 day ago

So it isn't just a matter of "they would use Rust instead".

There is a whole ecosystem of contributions across the globe and the lingua franca used by those contributors.

andriy_koval 16 hours ago

> There is a whole ecosystem of contributions across the globe and the lingua franca used by those contributors.

which is slowly changing with wider rust adaptation.

pjmlp 15 hours ago

Where are the LLVM pull requests adding Rust code?

andriy_koval 14 hours ago

I am not expert in compilers, but in databases space there are multiple prominent projects which gain traction, create ecosystem and making Rust strong contender against C++ dominance.

nindalf 20 hours ago

Same reason Android and Chrome and git and Linux weren't written in Rust when they started. Rust didn't exist. All of these projects integrate Rust now, after being single language projects for the longest time.

It's notable that the projects you mentioned mostly don't need to deal with adversarial user input, while the projects I mentioned do. That's one area that Rust shines in.

pjmlp 20 hours ago

Rust presence in Android is minimal, and not officially supported for userspace.

Android team is quite clear that Java, Kotlin, C and C++ are the official languages for app developers.

Chrome even has less Rust than Firefox.

Linux has some baby adoption, and it isn't without drama, even with Microsoft and Google pushing for it.

nindalf 19 hours ago

Rust will never be in Android user space, because it's not competing with Kotlin. Kotlin is already excellent there. Rust will replace the parts of Android written in C++ gradually. That was always the plan. It feels weird and cope-y to move the goalposts to say it's not a big deal unless Rust also replaces Kotlin.

Chrome only needs to replace the parts of their codebase that handle untrusted input with Rust to get substantial benefits. Like codec parsers. They don't need to rewrite everything, just the parts that need rewriting. The parts that are impossible to get right in C++, to the point where Chrome spins up separate processes to run that code.

Rust is the future for Android, and it will become an important of Chrome and Linux and git (starting 3.0). That's just the way it is.

flohofwoe 1 day ago

Looking at LLVM build times I seriously believe that C would have been the better choice :/ (it wouldn't be a problem if LLVM wouldn't be the base for so many other projects)

Same for the Metal shading language. C++ adds exactly nothing useful to a shading language over a C dialect that's extended with vector and matrix math types (at least they didn't pick ObjC or Swift though).

pjmlp 1 day ago

CUDA, SYSCL, HLSL evolution roadmap, and Khronos future for Vulkan beg to differ with your opinion.

flohofwoe 20 hours ago

> HLSL evolution roadmap

...that's just because of the traditional-game-dev Stockholm syndrome towards C++ (but not too much C++ please!).

> Khronos future for Vulkan

As far as I'm aware Khronos is not planning to move the Vulkan API to C++ - and the 'modern C++' sample code which adds a C++ RAII wrapper on top of the Vulkan C API does more harm than good (especially since lifetime management for Vulkan object is a bit more involved than just adding a class wrapper with a destructor).

pjmlp 20 hours ago

See the talks around Vulkan ecosystem, and GPU shading languages from February.

There is more than one sample using C++, now they make use of C++20, including modules if desired.

flohofwoe 18 hours ago

> now they make use of C++20, including modules if desired.

It's in line with many other shitty design decisions coming out of Khronos, so I'm not even surprised ;)

IMHO it's a pretty big problem when the spec is on an entirely different abstraction level than the sample code (those new samples also move significant code into 'helper classes', which means all the interesting stuff is hidden away).

quotemstr 1 day ago

Hilariously, they broke this compatibility. std::auto_ptr was an abomination, but removing it from the language was needless and undermined the long term stability that differentiates C++ from upstarts.

ChrisGreenHeur 1 day ago

those that used it were rightly punished by the removal

hansvm 23 hours ago

It's been a non-issue for us at tvScientific. Once or twice a year you settle in for a mass refactor, and when that's done you move on with your day.

Packages do fall behind. We only use a couple, so it's pretty easy to point to an internal fork while we wait for upstream to update or to accept our updates. That'd probably be a pain point if you were using a lot of them.

Cloudef 1 day ago

The language itself does not change much, but the std does. It depends on individuals, but some people rely less on the std, some copy the old code that they still need.

> Are there cases where packages you may use fall behind the language?

Using third party packages is quite problematic yes. I don't recommend using them too much personally, unless you want to make more work for yourself.

Zambyte 1 day ago

Using third party packages has gotten a lot easier with the changes described in this devlog https://ziglang.org/devlog/2026/#2026-02-06

hrmtst93837 1 day ago

Pinning your build chain and tooling to specific commits helps with stability but also traps you with old bugs or missing features. Chasing upstream fixes is a chore if you miss a release window and suddenly some depended package won't even compiile anymore.

Escapade5160 1 day ago

I recently tried to learn it and found it frustrating. A lot of docs are for 0.15 but the latest is (or was) 0.16 which changed a lot of std so none of the existing write ups were valid anymore. I plan to revisit once it gets more stable because I do like it when I get it to work.

Cloudef 1 day ago

0.16 is the development version. 0.15.2 is latest release.

boomlinde 1 day ago

I stopped updating the compiler at 0.14 for three projects. Getting the correct toolchain is part of my (incremental) build process. I don't use any external Zig packages.

I think one of the more PITA changes necessary to get these projects to 0.15 is removing `usingnamespace`, which I've used to implement a kind of mixin. The projects are all a few thousand LOC and it shouldn't be that much trouble, but enough trouble that none of what I gain from upgrading currently justify doing it. I think that's fine.

scuff3d 1 day ago

Mitchell Hashimoto (developer of Ghostty) talks about Zig a lot. Ghostty is written in it, and he seems to love it. The churn doesn't seem to bother him at all.

I asked him about in a thread a while back: https://news.ycombinator.com/item?id=47206009#47209313

The makers of TigerBeatle also rave about how good Zig is.

steeve 12 hours ago

hi, i'm the founder of https://github.com/zml/zml, very happy with Zig

sgt 1 day ago

> I know Bun's using zig to a degree of success, was wondering how the rest were doing.

Just a degree of success?

ptrwis 1 day ago

You can fix you code 10 times you will fix it.

throwaway27448 1 day ago

For those like me who have never heard of this software: Bun, some sort of package management service for javascript. https://en.wikipedia.org/wiki/Bun_(software)

beoberha 1 day ago

Bun is a full fledged JavaScript runtime! Think node.js but fast

throwaway27448 1 day ago

> Think node.js but fast

Color me extremely sceptical. Surely if you could make javascript fast google would have tried a decade ago....

leonflexo 1 day ago

Bun uses JSC (JavaScriptCore) instead of V8. From what I understand, whereas Node/V8 has a higher tier 4 "top speed", JSC is more optimized for memory and is faster to tier up early/less overhead. Good for serverless. Great for agents -> Anthropic purchase.

throwaway27448 1 day ago

> Good for serverless. Great for agents -> Anthropic purchase.

Surely nobody would use javascript for either yea? The weaknesses of the language are amplified in constrained environments: low certainty, high memory pressure, high startup costs.

leonflexo 1 day ago

I think Bun helps with the memory pressure, granted this is relative to V8. I'd pushback on the certainty with the reality that TS provides a significant drop in entropy while benefiting from what is a sweet spot between massive corpus size and low barrier for typical problem/use-case complexity. You'll never have the fastest product with JS, but you will always have good speed to market and be able to move quickly.

messe 1 day ago

> Surely nobody would use javascript for either yea?

It's probably the most popular language for serverless.

throwaway27448 1 day ago

I can't vouch for this behavior but obviously you can have a better serverless experience than writing lisp with the shittiest syntax invented by man

pjmlp 1 day ago

Only because the likes of Vercel and Netlify barely offer anything else on their free tiers.

When people go AWS, Azure, GCP,... other languages take the reigns.

ovao 23 hours ago

Do you have any stats on the latter?

pjmlp 22 hours ago

My own anecdote.

dtj1123 1 day ago

Claude CLI is based on bun. The dependency is so complete that Bun have now joined Anthropic.

throwaway27448 1 day ago

Claude CLI is not exactly a reference of usable software

mikkupikku 1 day ago

It's plenty usable. Most of the problems with the claude TUI stem from it being a TUI (no way to query the terminal emulator's displayed character grid), so you have to maintain your own state and try to keep them in sync, which more than a few TUIs will fail at at least sometimes, hence the popularity of conventions like Ctrl+L to redraw.

throwaway27448 19 hours ago

I don't know what a TUI is (i'm guessing "terminal ui" as if the term CLI doesn't exist lmao) but yea, they could have put effort into their product and not forced people to use their atrocious ncurses interface which is like the worst of all worlds: text interface without the benefit of the shell, zero accessibility.

mikkupikku 19 hours ago

CLI refers more to non-interactive programs used through a shell, programs like grep or or indeed the `claude` program in non-interactive modes. TUIs (text user interfaces) refers to interactive programs implemented in a terminal interface, what you call ncurses interfaces (but usually aren't implemented using ncurses these days.) They're GUIs in text, so TUIs.

Anyway, their decision to implement a TUI was definitely not done out of laziness nor even pragmatism. It was a fashion choice. A deliberate choice to put their product in the same vibes-space as console jockey hotshot unix pros who spit out arcane one liners to get shit done. They very easily could have asked claude to write itself a proper GUI interface which completely avoids all the pitfalls of TUIs and simplifies a lot of things they went out of their way to make work in a TUI. Support for drag-and-drop for instance, isn't something you'll find in many TUIs but they have it. They put care into making this TUI, the problem is that TUIs are kind of shit, and they certainly know that. They did it this way anyway effectively for marketting reasons.

throwaway27448 18 hours ago

Hmm. You've given me a lot to think about. I appreciate the effort, and thank you for replying with it.

rererereferred 1 day ago

The actual JS code is in the same ballpark as nodejs. They get fast by specializing to each platform's fastest APIs instead of using generic ones, reimplementing JS libraries in Zig (for example npm or jest) and using faster libraries (for example they use the oniguruma regex engine). Also you don't need an extra transpiling step when using TypeScript.

undeveloper 1 day ago

they have, v8 is a pretty fast engine and an engineering marvel. bun is faster at cost of having worse jit and less correctness

sidkshatriya 1 day ago

I am impressed by the achievements of the Zig team. I use the ghostty terminal emulator regularly -- it is built in Zig and it is super stable. It is a fantastic piece of software.

This makes me feel that the underlying technology behind Zig is solid.

But I prefer Rust over Zig. The main difference is Rust chooses a "closed world" model while Zig chooses an "open world" model: in Rust, you must explicitly implement a trait while in Zig as long as the shape fits, or the `.` on a structure member exists (for whichever type you pass in), it will work (I don't use Zig so pardon hand wavy description).

This gives Zig very powerful meta programming abilities but is a pain because you don't know what kind of type "shapes" will be used in a particular piece of code. Zig is similar to C++ templates in some respects.

This has a ripple effect everywhere. Rust generated documentation is very rich and explicit about what functions a structure supports (as each trait is explicitly enrolled and implemented). In Zig the dynamic nature of the code becomes a problem with autocomplete, documentation, LSP support, ...

Zanfa 1 day ago

> But I prefer Rust over Zig. The main difference is Rust chooses a "closed world" model while Zig chooses an "open world" model: in Rust, you must explicitly implement a trait while in Zig as long as the shape fits, or the `.` on a structure member exists (for whichever type you pass in), it will work (I don't use Zig so pardon hand wavy description).

Do you happen to have a more specific example by any chance? I’d be interested in what this looks like in practice, because what you described sounds a bit like Go interfaces and from my understanding of Zig, there’s no direct equivalent to it, other than variations of fieldParentPtr.

lukaslalinsky 1 day ago

They are referring to `anytype`, which is a comptime construct telling the compiler that the parameter can be of any type and as long as the code compiles with the given value, it's good.

It's an extremely useful thing, but unconstrained, it's essentially duck typing during compile time. People has been wanting some kind of trait/interface support to constrain it, but it's unlikely to happen.

OskarS 1 day ago

Conceptually it's quite similar to how C++ templates work (not including C++20 concepts, which is the kind of constraining you're talking about).

I quite like it when writing C++ code. Makes it dead easy to write code like `min` that works for any type in a generic way. It is, however, arguably the main culprit behind C++s terrible compiler-errors, because you'll have standard library functions which have like a stack of fifteen generic calls, and it fails really deeply on some obscure inner thing which has some kind of type requirement, and it's really hard to trace back what you actually did wrong.

In my (quite limited) experience, Zig largely avoids this by having a MUCH simpler type system than C++, and the standard library written by a sane person. Zig seems "best of both worlds" in this regard.

seivan 1 day ago

[dead]

king_geedorah 22 hours ago

The kernel32 -> Ntdll changes are the most interesting thing to me here. A lot of the rationale is applicable also to the linux userspace APIs, especially errors in return at the kernel-userspace boundary vs GetLastError/errno in kernel32/libc. Of course on linux the "problem" is that libc and the kernel API are intimately intertwined and the former mandates using errno. I wonder how the pattern made its way into windows as well. That environment has never seemed to me to promote using libc.

simonask 22 hours ago

The errno/GetLastError() pattern is a remnant from a time before threads were a thing. You could have multiple processes, but they were largely scheduled collaboratively (rather than preemptively).

In that world, things like global variables are perfectly fine. But then we got first preemptive scheduling and threads, then actual multicore CPUs, so global variables became really dangerous. Thread locals are the escape hatch that carried these patterns into the 21st century, for better or worse.

jlokier 20 hours ago

Indeed, and this change of philosophy shows up in the pthread (POSIX threads) API, which returns error values directly (as a negative integer) instead of setting the errno variable.

sesm 1 day ago

Instead of implementing a workaround for types as namespaces, wouldn't it better to explicitly add namespaces to the language?

txdv 21 hours ago

I think zig is striving for language minimalism, make it minimal as possible then if a feature optimized multiple places use cases benefit

Arch485 22 hours ago

It's not so much a workaround as it is an elegance in design. In Zig, when you @import a file, that file is converted to a struct with comptime fields for all of the public members. Similarly, a "namespace" in Zig is just a nested struct with more fields. Usually it's just another import of something else.

N.B.: Coffee hasn't reached my bloodstream yet; accuracy not guaranteed.

peesem 7 hours ago

files aren't converted to structs on import, they _are_ structs (well, their contents are the inside of a struct declaration). also, public members don't become comptime fields? file structs are basically left as-is on import, nearly like you copy&pasted the file contents into a struct declaration

lerno 20 hours ago

I just have to add another reflection:

One thing that tends to be overlooked when discussing changes is the ecosystem effect of frequent changes.

A language that breaks frequently doesn't just impose upgrade work on apps, but also discourages the creation of long-lived libraries and tools. Anything that sits between the language and the user (linters, bindings, frameworks, teaching material, tutorials etc) has to to some degree "chase the language"

This means that the ecosystem will skew toward very actively maintained libraries and away from "write once then leave it alone" libs. And this the trade-off is reasonable during early language design, but it's worth acknowledging that it has real consequences for ecosystem growth.

One should note that other newer languages have put significant effort into minimizing this churn, precisely to allow the latter type of ecosystem to also form. So it's kind of an experiment, and it will be interesting to see which approach ends up producing the larger ecosystem over time.

riidom 19 hours ago

An example for this is the Blender addon ecosystem. Blender moves very fast, breaking API changes every few versions. Now I am not an addon developer myself, but from github issues I follow, changes are fairly often trivial to do.

Yet, someone has to do them. Ideally it is the creator of the addon, sometimes it's the users who do it, when the addon is not maintained anymore (in case of trivial changes).

It kinda works that way, but it also is some kind of gamble for the user. When you see a new addon (and a new addon developer), you can't know if they gonna stick to it or not.

If you have to pay for the addon, it's more likely they maintain it, of course. But also not a guarantee.

bro45x 18 hours ago

Zig's worth it though. I don't care for libraries that aren't maintained anyway. If they don't maintain it, it's just bad anyway. Why do you always nag about Zig. Stop shilling your C3 here.

MintPaw 18 hours ago

This kind of thought is popular in the web world where browsers get an update every 3 days and you don't control the hosting services, so constant maintenance is unavoidable.

But in the world of desktop development it's possible for a library to be "done", having a 100% stable codebase going forward and requiring no maintenance. And it's not bad, it's actually good.

Requiring every dependency to be constantly maintained is a massive drain on productivity.

bro45x 13 hours ago

Looks like all the 2 users of C3 came here to complain about Zig. Why should we listen to you?

ChrisSD 22 hours ago

> Many projects including Chromium, boringssl, Firefox, and Rust call SystemFunction036 from advapi32.dll because it worked on versions older than Windows 8.

That's not true. They use ProcessPrng since versions earlier than 10 are no longer supported (well, rust also has a windows 7 target but that couldn't use ProcessPrng anyway since it wasn't available). The issue they linked is from a decade ago. E.g. here's Chromium: https://github.com/chromium/chromium/blob/dc7016d1ef67e3e128...

> If [ProcessPrng] fails it returns NO_MEMORY in a BOOL (documented behavior is to never fail, and always return TRUE).

From Windows 10 onward ProcessPrng will never fail. There's a whitepaper that gives the justification for this (https://aka.ms/win10rng):

> We also have the property that a request for random bytes never fails. In the past our RNG functions could return an error code. We have observed that there are many callers that never check for the error code, even if they are generating cryptographic key material. This can lead to serious security vulnerabilities if an attacker manages to create a situation in which the RNG infrastructure returns an error. For that reason, the Win10 RNG infrastructure will never return an error code and always produce high-quality random bytes for every request...

> For each user-mode process, we have a (buffered) base PRNG maintained by BCryptPrimitives.dll. When this DLL loads it requests a random seed from kernel mode (where it is produced by the per-CPU states) and seeds the process base PRNG. If this were to fail, BCryptPrimitive.dll fails to load, which in most cases causes the process to terminate. This behavior ensures that we never have to return an error code from the RNG system.

winterqt 21 hours ago

(This is a response to a different devlog entry on the same page, not TFA.)

ChrisSD 20 hours ago

Oh sorry, I thought this was just listing changes since the branch.

xthunk 10 hours ago

One thing I’ve noticed reading Zig discussions is that many semantics seem simple on their own but interactions can be subtle – like in the behavior fixed here.

I wonder if this ends up similar to C++ template rules where the surface looks small but the edge cases accumulate over time.

throwaway17_17 1 day ago

Congratulations to the dev, a 30,000 line PR for a language compiler (and a very much non-trivial compiler) is a feat to be proud of. But a change of this magnitude is a serious bit of development and gave me pause.

I understand both of the following:

1. Language development is a tricky subject, in general, but especially for those languages looking for wide adoption or hoping for ‘generational’ (program life span being measured in multiple decades) usage in infrastructure, etc.

2) Zig is a young-ish language, not at 1.0, and explicitly evolving as of the posting of TFA

With those points as caveats, I find the casualness of the following (from the codeburg post linked on the devlog) surprising:

‘’’This branch changes the semantics of "uninstantiable" types (things like noreturn, that is, types which contain no values). I wasn't originally planning to do this here, but matching the semantics of master was pretty difficult because the existing semantics don't make much sense.’’’

I don’t know Zig’s particular strategy and terminology for language and compiler development, but I would assume the usage of ‘branch’ here implies this is not a change fully/formally adopted by the language but more a fully implemented proposal. Even if it is just a proposal for change, the large scale of the rewrite and clear implication that the author expects it to be well received strikes me as uncommon confidence. Changing the semantics of a language with any production use is nearly definitionally MAJOR, to just blithely state your PR changes semantics and proceed with no deep discussion (which could have previously happened, IDK) or serious justification or statements concerning the limited effect of those changes is not something I have experienced watching the evolution (or de-evolution) of other less ‘serious’ languages.

Is this a “this dev” thing, a Zig thing, or am just out of touch with modern language (or even larger scale development) projects?

Also, not particularly important or really significant to the overall thrust of TFA, but the author uses the phrase “modern Zig”, which given Zig’s age and seeming rate of change currently struck me as a very funny turn of phrase.

munificent 1 day ago

When someone's communication is casual and informal, without any context, you really can't distinguish between:

* The author is being flippant and not taking the situation seriously enough.

* The author is presuming a high-trust audience that knows that they have done all the due diligence and don't have to restate all of that.

In this case, it's a devlog (i.e. not a "marketing post") for a language that isn't at 1.0 yet. A certain amount of "if you're here, you probably have some background" is probably reasonable.

The post does link directly to the PR and the PR has a lot more context that clearly conveys the author knows what they are doing.

It is weird reading about (minor) breaking language changes sort of mentioned in passing. We're used to languages being extremely stable. But Zig isn't 1.0 yet. Andrew and friends certainly take user stability seriously, but you signed up for a certain amount of breakage if you pick the language today.

As someone who maintains a post-1.0 language, there really is a lot of value in breaking changes like this. It's good to fix things while your userbase is small. It's maddening to have to live with obvious warts in the language simply because the userbase got too big for you to feasibly fix it, even when all the users wish you could fix it too. (Witness: The broken precedence of bitwise operators in C.)

It's better for all future users to get the language as clean and solid as you can while it's still malleable.

smj-edison 1 day ago

mlugg is one of the core contributors of Zig, and is a member of the Zig foundation iirc. They've been wanting to work on dependency resolution for a while now, so I'm really glad they're cleaning this up (I've been bitten before by unclear circular dependency errors). There's not a formal language spec yet, since it's moving pretty fast, but tbh I don't see the need for a standard, since that's not one of their goals currently.

AndyKelley 1 day ago

Originally, Zig's type system was less disciplined in terms of the "zero" type (also known as "noreturn").

This was proposed, discussed, and accepted here: https://github.com/ziglang/zig/issues/3257

Later, Matthew Lugg made a follow-up proposal, which was discussed both publicly and in ZSF core team meetings. https://github.com/ziglang/zig/issues/15909

He writes:

> A (fairly uncontroversial) subset of this behavior was implemented in [the changeset we are discussing]. I'll close this for now, though I'll probably end up revisiting these semantics more precisely at some point, in which case I'll open a new issue on Codeberg.

I don't know how evident this is to the casual HN reader, but to me this changeset very obviously moves Zig the language from experimental territory a large degree towards being formally specified, because it makes type resolution a Directed Acyclic Graph. Just look at how many bugs it resolved to get a feel for it. This changeset alone will make the next release of the compiler significantly more robust.

Now, I like talking about its design and development, but all that being said, Zig project does not aim for full transparency. It says right there in the README:

> Zig is Free and Open Source Software. We welcome bug reports and patches from everyone. However, keep in mind that Zig governance is BDFN (Benevolent Dictator For Now) which means that Andrew Kelley has final say on the design and implementation of everything.

It's up to you to decide whether the language and project are in trustworthy hands. I can tell you this much: we (the dev team) have a strong vision and we care deeply about the project, both to fulfill our own dreams as well as those of our esteemed users whom we serve[1]. Furthermore, as a 501(c)(3) non-profit we have no motive to enshittify.

[1]: https://ziglang.org/documentation/master/#Zen

It's been incredible working with Matthew. I hope I can have the pleasure to continue to call him my colleague for many years to come.

tialaramex 1 day ago

Where does the name "zero type" come from? In type theory this is called an "empty" type because the set of values of this type is empty and I couldn't find (though I have no idea where to start) mention of it as a "zero" type.

This stuff is foundational and so it's certainly a priority to get it right (which C++ didn't and will be paying for until it finally collapses under its own weight) but it's easier to follow as an outsider when people use conventional terminology.

Cloudef 1 day ago

I think rust calls them "zero sized types".

tialaramex 23 hours ago

The ZSTs are unit types. They have one value, which we usually write as just the type name, so e.g.

    struct Goose;

    let x = Goose; // The variable x has type Goose, but also value Goose, the only value of that type
The choice to underscore that Rust's unit types have size zero is to contrast with languages like C or C++ where these types, which don't need representing, must nevertheless take up a whole byte of storage and it's just wasted.

But what we're talking about here are empty types. In Rust we'd write this:

    enum Donkey {}

    // We can't make any variables with the Donkey type, because there are no values of this type and a variable needs a value
mk12 1 day ago

No, that’s a different thing. “noreturn” is like Rust’s “never” type (spelled as an exclamation mark, !). Also known as an “uninhabited type” in programming language theory.

tialaramex 22 hours ago

Note that Rust's ! isn't stabilized, however you can (in stable Rust, today) make your own empty/ uninhabited types, yours just isn't "the" canonical empty type for the language, and so the type arithmetic won't necessarily see that it's the same thing in some cases if that matters.

Rust's core::convert::Infallible is such a type, representing in that case the error type for conversions which have no errors. For example, we can try to convert most numeric types into a 16-bit unsigned type, and obviously most of them can fail because your value was too big or negative or whatever. u16 however obviously never fails, the conversion is a no-op, nevertheless it would be stupid if we can't write generic code to convert it - so of course we can, and if we wrote generic error handling code, that code is dead for the u16 case, we can't fail, the use of empty types here justifies the compiler saying OK, that code is dead, don't emit it. Likewise converting u8 to u16 can't fail - although it's slightly more than a no-op in some sense - and so again the error handling is dead code.

Cloudef 22 hours ago

I see. I can not give more insightful answer here then. From personal experience, I've noticed with 0.16 with the std.Io async stuff that you cannot do:

   io.concurrent(foo, .{});
where foo's return type is `error{foobar}!noreturn`, because the compiler crashes when it tries to use that type as a std.Io.Future(T)'s struct field. Might be related or not.
mlugg 21 hours ago

It is indeed (somewhat) related, and in fact that was fixed by this PR: https://github.com/ziglang/zig/issues/25771

throwaway17_17 22 hours ago

Thanks for the reply Andrew, I certainly did not mean to imply any issues with trustworthiness for Zig users or prospective adopters. Also, I absolutely did not intend to imply any negatives toward Zog’s evolution or this particular development on the compiler’s internals.

I enjoy all of the process and implementation content, i.e. videos, podcast, and blogs that yourself and contributors have provided through various platforms over the years. I made a comment from a relatively u informed place and it seems to have been taken as a negative remark on Zig or the language and compiler’s development. Apologies if it was seen that way yourself or other contributors.

As for Matthew, the work both planning and implementing these changes was clearly a large undertaking and I certainly applaud that and hope no one thought otherwise.

bro45x 11 hours ago

Zog? What the hell man.

norman784 1 day ago

I don't use Zig (is not a language for me), but I like to read/watch about it, when you or others talk about the language design and the reasons behind the changes.

Thanks for your and the Zig team work.

hitekker 1 day ago

> Zig the language from experimental territory a large degree towards being formally specified

Great to hear; I look forward to reading the language spec one day.

bro45x 11 hours ago

You're the man Kelley, don't let the doomers get to you

jibal 1 day ago

[flagged]

saghm 1 day ago

They literally ended the comment by asking. I don't get why you're criticizing them for providing context that they're not an expert. You're literally distracting from the comment you're telling them has useful information on it, but in a weirdly aggressive way.

8n4vidtmkvmk 1 day ago

This seems unnecessarily hostile. They are asking. Here.

jhatemyjob 18 hours ago

It seems hostile to you, but surely you can see what he's replying to is way more hostile and passive aggressive?

rowanG077 1 day ago

Just thinking out loud here, perhaps behavior like this has been more normalized because of the total shitshow that C is. Which followed all these supposedly correct rules.

sharyphil 21 hours ago

Move 'ZIG'.

burgerone 20 hours ago

What makes zig special as a language? I have the impression that it has quite a large fan base here on HN but don't really hear any talks about it anywhere else.

skavi 12 hours ago

Disclaimer: I don't really use Zig (primarily a Rust dev) but I do think it's quite cool.

If you're willing to dive right into it, I'd first read a bit about the comptime system [0] then have a go at reading the source for `MultiArrayList` [1], a container which internally stores elements in SoA format.

At least, that was what got me interested.

[0]: https://ziglang.org/documentation/master/#comptime

[1]: https://codeberg.org/ziglang/zig/src/branch/master/lib/std/m...

portly 18 hours ago

I can share mine. I am not sure if this connects with you because maybe you are more experienced.

I'm DevOps writing boring Python microservices for €. I have no CS background and never did systems programming. However, writing Python always bothered me because there are so many layers between you and what's happening on the metal. For me, Django is the peak example of this, to me it feels almost like doing no code. It makes me very uncomfortable writing it.

Then I heard about this new programming language Zig on YouTube and I just gave it a try. After using it for a few months, I really like it. I guess mostly because it is so explicit.

It is almost like the language encourages you to think in terms of system design. Zig offers a lot of freedom so you can design the perfect tool for your problem. And somehow, it feels very effective for it. I think it is a blessing that there are few third party libraries for the same reason.

For example. I am working on a tool to parse CIM (some XML standard). If I had to use Python for this, my solution would probably use the most popular xml parsing library and then go from there. Yawn.

Instead, with Zig I started to think with a very fresh mind about the problem. I started thinking more from the first principles of the problem. And I got very excited again about programming. During my swimming practice or biking, I kept thinking about the design and how I can make it simpler and improving it by simply not doing certain busy work. I can't fully explain it. But the language gets you in that mindset.

Maybe other system languages also offer this experience, Zig (marketing?) just happened to cross my paths at the right moment.

Tadpole9181 17 hours ago

I'm sure it's not what you meant, but the argument "it makes me slower at my job and deliver less stable solutions, but I feel cool doing it" is not exactly a compelling endorsement.

lerno 1 day ago

It’s good to see that this is finally addressed. It’s been a well known broken part of the language semantics for years.

There are similar hidden quirks in the language that will need to be addressed at some point, such as integer promotion semantics.

To address the question about stability: the Zig community are already used to Zig breaking between 0.x versions. Unlike competitors such as Odin or my own C3, there is no expectation that Zig is trying to minimize upgrading problems.

This is a cultural thing, it would be no real problem to be clear about deprecations, but in the Zig community it’s simply not valued. In fact it’s a source of pride to be able to adapt as fast as possible to the new changes.

I like to talk about expectation management, and this is a great example of it.

In discussions, it is often falsely argued that ”Zig is not 1.0 so breaks are expected” in order to motivate the frequent breaks. However, there are degrees to how you handle breaks, and Zig is clearly in the ”we don’t care to reduce the work”-camp.

If someone is trying to get a more objective look at the Zig upgrade path, then it’s worth keeping in mind that the tradition in Zig is to offload all the work on the user.

The argument, which is frequently voiced, is that ”breaking things will make the language get better and so it’s good that there are language breaks”

It is certainly true that breaking changes are needed, but most people outside of the Zig community would expect it to be done with more care (deprecation paths etc)

Secondly, it should perhaps be a concern for Zig, now at 10 years old, to still produce solidly breaking code every half year.

10 years is the common point where languages go 1.0. However, the outlook for a Zig 1.0 is bleak from what I gather from Zig social forums: the most optimistic estimate I’ve heard is 2029 for 1.0.

This means that in the future, projects using Zig can still expect any libraries and applications to bitrot quickly if they are not constantly maintained.

Putting this in contrast with Odin (9 years old) which is essentially 1.0 already and has been stable for several years.

Maybe this also explains the difference in actual output. For example the number of games I know of written in Odin is somewhere between 5 to 10 times as many as Zig games. Now weighing in that Zig has maybe 5 or 10 times as many users, it means Odin users are somewhere between 20-100 times as likely to have written a playable game.

There are several explanations as to why this is: we could discuss whether the availability of SDL, Raylib etc is easier on Odin (then why is Zig less friendly?), maybe more Odin has better programmers (then why do better programmers choose Odin over Zig), maybe it’s just easier to write resource intensive applications with Odin than Zig (then what do we make of Zig’s claim of optimality?)

If we look past the excuses made for Zig (”it’s easy to fix breaks” ”it’s not 1.0”) and the hype (”Zig is much safer than C” ”Zig makes me so productive”) and compare with Odin in actual productivity, stability and compilation speed (neither C3 nor Odin requires 100s of GB of cache to compile in less than a second using LLVM) then Zig is not looking particularly good.

Even things like build.zig, often touted as a great thing, is making it really hard for a Zig beginner (”to build your first Hello World, first understand this build script in non-trivial Zig”). Then for IDEs, suddenly something like just reading the configuration of what is going to be used for building is hidden behind an opaque Zig script. These trade-offs are rarely talked about, as both criticism and hype is usually based on surface rather than depth.

Well, that’s long enough of a comment.

To round it off I’d like to end on a positive note: I find the Zig community nice and welcoming. So if you’re trying Zig out (and better do that, don’t let others’ opinions - including mine - prevent you from trying things out) do so.

If you want to evaluate Zig against competitors, I’d recommend comparing it to D, Odin, Jai and C3.

peesem 7 hours ago

it seems to me like the acceptance of breaking changes by the Zig community is more coming from "it's worth it to get a nice, polished language" than some "source of pride" which i personally have not seen in my time in a/the Zig discord server.

what is the problem with zig being developed for 10+ years? if people want stable languages there are stable languages to be used. if a language like zig is not achievable in less than 10 years, should it just not be developed from the start?

i think your problems with build.zig are overstated. where do you see someone saying "to build your first Hello World, first understand this build script in non-trivial Zig"? you can literally just do `zig run file.zig`, so if someone is advocating for that then i think many would agree they are teaching the wrong way. i wonder if you saw an example project with a build script that was intended to show the power and possibilities of Zig rather than to be a starter guide.

jackhalford 23 hours ago

> Secondly, it should perhaps be a concern for Zig, now at 10 years old, to still produce solidly breaking code every half year.

Not at all, if the team needs 30 more years they should take it.

> However, the outlook for a Zig 1.0 is bleak from what I gather from Zig social forums: the most optimistic estimate I’ve heard is 2029 for 1.0.

Funny you see it as bleak when most of the community sees it as the most excitinh thing in systems programming happening right now.

I think you comment is in bad faith, all the big zig projects say that the upgrade path is never a main concern, just read HN comments here or on other zig threads, people ask about this a lot and maintains always answer.

lerno 20 hours ago

> Not at all, if the team needs 30 more years they should take it.

Yes, I understand that is the opinion in the Zig community. As an outsider, it seems odd to me to pick a language that I constantly need to maintain.

>> However, the outlook for a Zig 1.0 is bleak from what I gather from Zig social forums: the most optimistic estimate I’ve heard is 2029 for 1.0.

> Funny you see it as bleak when most of the community sees it as the most excitinh thing in systems programming happening right now.

You misread that one. I was talking about the odds of seeing a 1.0 version of Zig soon.

> I think you comment is in bad faith, all the big zig projects say that the upgrade path is never a main concern, just read HN comments here or on other zig threads, people ask about this a lot and maintains always answer.

Maybe you didn't read what I wrote carefully enough. This is part of the protectiveness from the Zig community that prompted me to write in the first place.

WITHIN the Zig community it is deemed acceptable for Zig upgrades to break code. Consequently it becomes simple survivor bias that people who use Zig for larger projects don't think that this is a major concern BECAUSE IF THEY FELT IT WAS A CONCERN THEY WOULD NOT USE ZIG.

Whether programmers at large feel that this is a problem is an unknown still, since Zig has not yet reached to point of general adoption (when people use Zig because they have to, rather than because they want to).

However, it is INCORRECT to state that just because a language is not yet 1.0 it needs to break older code aggressively without deprecation paths. As an example, Odin removed the old `os` module and replaced it with the new "os2". This break was announced half a year in advance and lots of thought was put into reducing work for developers: https://odin-lang.org/news/moving-towards-a-new-core-os/

In the case of C3, breaking changes only happen once a year with stdlib going through the general process of deprecating functions long before removing them.

I wanted to highlight how these are quite different approaches. For established languages, this is of course even more rigorous, but neither C3 nor Odin are 1.0, and still see this as valuable and their communities then end up expecting it.

So please understand that when you say "it's never a main[sic] concern", this is simple survivor bias.

_bohm 21 hours ago

A pretty obvious explanation as to why Odin has more games written in it is that the language is somewhat explicitly marketed towards that use-case, even going as far to have a vendor library collection that includes many popular game dev libraries.

lerno 20 hours ago

I am using games, because they pop up more often (gamejams etc), but we can see the same if we'd look at utility apps. Do you want to broaden that to "Odin is more explicitly marked towards writing applications", but if so what would that say of Zig?

_bohm 20 hours ago

I would begin by questioning the premise. Do you have actual numbers on this? I’m not really aware of any widely adopted software that’s written in Odin. Can name multiple in the case of Zig

bro45x 18 hours ago

Zig is great. If frequent updates are the price for that, so be it.

Honestly it’s kind of narrow-minded not to appreciate how different its approach to low-level programming is. You either see it or you don’t.

C3 is basically just C with a few extra bells and whistles. Still the same old C. Why would I use that when Zig exists? Actually never mind, don’t bother answering.

And the doomer posts are so predictable. That’s usually when you know Zig is doing something right.

yowang 22 hours ago

[dead]

raphaelmolly8 18 hours ago

[dead]

patchnull 16 hours ago

[flagged]

ansi_c 1 day ago

[dead]

saritekin 23 hours ago

[flagged]

postflopclarity 22 hours ago

please don't use AI to write comments

nindalf 22 hours ago

dang can we please ban any user that writes comments with AI?

patchnull 1 day ago

[flagged]

sethops1 20 hours ago

AI slop. Get lost.