top | item 32187626

Some Thoughts on Zig

170 points| todsacerdoti | 3 years ago |v5.chriskrycho.com | reply

275 comments

order
[+] socialdemocrat|3 years ago|reply
Nice balanced writeup! However, I am not convinced one can make something solving all the things Rust solves which is substantially simpler as language.

Whether we look at Zig, Go or Julia they stay relatively simple because they simply avoid solving certain problems. I think that is a fair tradeoff. I think good language design is really about figuring out what problems can we dump on the user which they will be able to handle relatively well.

A reason why there are so many languages I think is because different people have different preferences in terms of what problems the want to avoid dealing with and what problems they are fine dealing with.

Personally I think that if you "solve" a problem by making the language so complex that developers cannot easily read and reason about the code, then you haven't actually solved any problem. Priority must always be placed on the ability of developers to read and understand code.

Unreadable code will naturally be a source of bugs.

[+] josephg|3 years ago|reply
> However, I am not convinced one can make something solving all the things Rust solves which is substantially simpler as language.

I wonder a lot about this too. As far as I know, rust is alone. It’s the first language to exist which does compile time memory management in a safe way. Every other language either is memory-unsafe (C, Zig) or garbage collected. (Go, JS, etc).

Rust might the first language of its kind, but it probably won’t be the last. I’d be very surprised if we’re still using rust 100 years from now. Subsequent languages can learn from rust’s accidental complexity and clean up the approach.

Personally I suspect it’s possible to have a borrow checked language that’s much simpler than rust. I don’t know what that would look like, but it would be surprising to me if we found the best programming language in this space on our (collective) first attempt at it.

But I don’t have enough insight to figure out what rust’s successor would look like either. But luckily for both of us, there are a lot of smart people thinking about the problem now. Let’s give it a decade and see.

[+] verdagon|3 years ago|reply
> Nice balanced writeup! However, I am not convinced one can make something solving all the things Rust solves which is substantially simpler as language.

I used to think this too, but my opinions have evolved a bit.

Recall the transition from goto-heavy assembly code to C; it solved all the things assembly solved, and was a substantially simpler language. One of the keys to designing a good language (or any good abstraction, really) is to identify the patterns that already informally exist.

So if we want to see a simpler Rust, we need to look at the informal patterns that exist in Rust.

* Zig did this with Rust's async/await, by making it colorblind. [0]

* Vale did this with Rust's generational indices, by making generational references, a way to get memory-safe single ownership without a borrow checker. [1] It then adds a hardened FFI boundary to get more solid safety guarantees than Rust could. [2]

* HVM did this for Haskell by looking at Rust's particular blend of borrowing and cloning, and making it happen automatically. [3]

* Lobster did something similar for an imperative mutable language, to reduce RC costs lower than ever before. [4]

I think Rust is an amazing first attempt at an interesting new problem space, and a huge step forward for the field. Now, language designers are starting to notice that the building blocks that Rust trailblazed might be combined in new interesting ways, to make new interesting languages.

It's an exciting time for programming languages!

[0] https://kristoff.it/blog/zig-colorblind-async-await/

[1] https://verdagon.dev/blog/generational-references

[2] https://vale.dev/memory-safe

[3] https://github.com/Kindelia/HVM

[4] https://www.strlen.com/lobster/

[+] Nadya|3 years ago|reply
I'm keeping an eye on Vale [0] but will continue to use Rust for hobby projects because the community/tooling that has built around it has made it much easier over a few years than when I first gave it a try in 2018 and especially as support for development on Windows grew. I went from absolutely struggling to get so much as a win32 GUI window to open [1] to writing a basic counting app [2] for a game I play to completely rewriting that app to not suck [3] (even though the code is still awful).

Zig looks nice to read and understand. However at my skill level (more or less a skript kiddie) I don't trust myself to not cause major memory-related bugs. In fact, I can't help but wonder if it's hubris or what when extremely intelligent, college educated, programmers with more than my lifetime of experience who still manage to write programs riddled with memory safety issues and in the very next breathe say memory safety isn't an issue just write safe code. I wonder what skill/knowledge thresholds are where "I don't trust myself to not make those mistakes" turns into "I won't make those mistakes."? Honestly it reminds me of the low IQ/high IQ meme [4].

[0] https://vale.dev/

[1] https://gitlab.com/NadyaNayme/rusty-eyes

[2] https://github.com/NadyaNayme/Dorothy

[3] https://github.com/NadyaNayme/Dorothy-egui

[4] https://kimiwo.aishitei.ru/i/sZaEWnY3NvfXecLm.png

[+] kaba0|3 years ago|reply
I have to agree. Adding safe, non-automatic memory management to a language will increase its complexity considerably, and I don’t see it changing even with the below mentioned new languages/techniques. Even just fundamentally, manual memory management begets functions that know about the memory architecture of your program, solidifying a given architecture. Changing this latter will result in a recursive refactor, which even if safe, is problematic/complex.

Sure, it is a worthy tradeoff in certain, very niche cases (though other than writing other performant runtimes and realtime audio processing, I fail to see another area where a GC couldn’t fit - including even OSs), for which we need a language, but I really don’t get this recent hate for garbage collection, when it is truly one of the biggest productivity improvements for a PL, while simultaneously it being very performant (quite likely outperforming any naive manual take on more complex problems).

[+] Tozen|3 years ago|reply
> ...Priority must always be placed on the ability of developers to read and understand code.

The importance of this can't be overlooked, which is debatably why people and companies are constantly looking for a way to escape heavily complex languages and syntax. It is part of the thinking behind somewhat newer languages like Go, or newer offshoots like Vlang (https://vlang.io/), which has a focus on high readability and general usability.

If a language is being geared towards the majority or mass appeal, then it has to find that correct sweet spot. There is simply going to be a cap on how far complexity will be embraced or how much specialization will be found useful.

“Genius is making complex ideas simple, not making simple ideas complex.” — Albert Einstein

> ...I am not convinced one can make something solving all the things Rust solves which is substantially simpler as language.

Debatably, such languages making the attempt, are less likely to succeed. Off rip, Rust already occupies that space. So, trying to make a "better Rust", which is already a specialist in that field (safety) and has already got "the push" from large corporate backers (Mozilla, Samsung, Quantum...) will usually mean failure, remaining in niche status, or overcoming incredible odds (like hitting a Lotto jackpot). The more the language specializes on that particular use case, then arguably the less general appeal and general use. And if there is already competition doing it better or being more known for that focus, the harder the hill to climb.

For that matter, trying to make a "better C", is another tough hill. Not only because C is so entrenched and established, but that there is already a long list of quasi "better Cs" out there such as Object Pascal, D, Nim, etc... Add in more complex or confusing syntax, less features, less functionality, or less usefulness... Then the hill gets even more steep. Hitting the bullseye, just isn't easy.

[+] vageli|3 years ago|reply
> Whether we look at Zig, Go or Julia they stay relatively simple because they simply avoid solving certain problems.

Could you expand on the specific problems that each language avoids?

[+] agentultra|3 years ago|reply
Unreadable as in, “this code is unfamiliar and I haven’t talent the time to understand it,” or “this code is syntactically designed to be difficult to parse by humans and I cannot read it?”
[+] gavinhoward|3 years ago|reply
I think you are absolutely right about everything you mentioned, except for one:

> I am not convinced one can make something solving all the things Rust solves which is substantially simpler as language.

You could be right about this, but boy, I hope you are wrong. And I'm trying to prove that it's possible.

I think the answer is structured concurrency [1], and here's why:

1. Structured concurrency can replace everything async/await can do. At least, I believe so, kind of like it's believed that structured programming can replace any unstructured use of goto.

2. If you extend structured concurrency a bit so that the thread tree is actually a DAG [2], you basically get a borrow checker for free because every item is rooted in a thread stack somewhere, and where it is rooted is always before everything that it could own and after everything that could own it.

3. Making the thread tree a DAG also means it's easy to implement RAII and have it work meaning no use-after-free, no double frees, etc.

Put that on top of a language that has memory safety by default, and you will have everything that Rust gives you without the complexity.

This isn't theoretical; I have implemented this in C. [3] (See [4] for a use of it.) I have even implemented bounds checking in C. [5]

However, I'm also implementing a programming language with these ideas (see [6] for the example file and [7] within that file for how structured concurrency might be exposed in the language).

As for readability, I do think that what I have is readable. However, I appreciate comments; readability is important to me too, but I've spent so long with this work that I am blind to what is actually readable to other people.

[1]: https://gavinhoward.com/2019/12/structured-concurrency-defin...

[2]: https://lobste.rs/s/8msejg/notes_on_structured_concurrency_g...

[3]: https://git.yzena.com/Yzena/Yc/src/branch/master/include/yc/...

[4]: https://git.yzena.com/Yzena/Yc/src/branch/master/src/rig/bui...

[5]: https://git.yzena.com/Yzena/Yc/src/branch/master/include/yc/...

[6]: https://git.yzena.com/Yzena/Yc/src/branch/master/src/yao/exa...

[7]: https://git.yzena.com/Yzena/Yc/src/branch/master/src/yao/exa...

[+] ArrayBoundCheck|3 years ago|reply
I never tried zig but I want to address something the article wrote

> People struggle with Rust for a number of reasons ... the borrow checker!

The borrow checker was the easiest thing for me to learn and the only thing I liked about rust. Except it's broken. I have to constantly reborrow after calling a constant function. The reason I actually bailed on rust is because it's a worse C++ (compiles slower, executes slower, isn't compatible with C's __thread etc etc), it's a worse webserver (I still use PHP and C#), it's worse for database heavy code, it's not very good for one offs (C# and python are better), it basically cost too much to switch for the broken borrow checker

Also the article at the end doesn't make it clear what he thinks. Usually I read the start and end to see if I'm interested in the topic and I'm not sure if this article is in secret a rant

[+] nemothekid|3 years ago|reply
>I have to constantly reborrow after calling a constant function.

Not sure what you mean by this, do you have an example?

[+] swsieber|3 years ago|reply
The borrow checker has been through a couple revisions now, and it's got better each time.
[+] LAC-Tech|3 years ago|reply
I am all in on Zig. I was more producitve with it in a few weeks than I was after a few months of rust. Yes the memory management is "manual" but the std library functions for dealing with it are top notch, you have to free a lot less due to the ease of using arena allocators, and the testing allocator does a valgrind-esque runtime analysis of your code - very quickly and very thoroughly. In practice, it's not an issue, and unlike with rust I have a very clear idea of when and where memory is being freed and allocated.

That having been said - the core team chooses some incredibly dumb hills to die on. Last time I checked the tab character was illegal in Zig code - though I understand that's changing.

More concerning is that un-named parameters are a compiler error and this cannot be adjusted. Meaning that if you want to test on save, you can't if any of your parameters are unused. Enforcing such a thing at the compiler level because of your personal coding style is so mind-numbingly short sighted. The guy who made it is clearly a very smart and insightful, but I acknowledge you probably have to be fairly stubborn to decide you're going to replace C.

[+] pcwalton|3 years ago|reply
> In practice, it's not an issue, and unlike with rust I have a very clear idea of when and where memory is being freed and allocated.

I'm very skeptical that the lack of memory safety is not going to be an issue "in practice". That's what every C++ developer thinks too until they write code people actually try to attack.

One of the very nice things about memory safety is that it frees the programmer from having to think about when memory is freed most of the time. The compiler or runtime system will take care of that. Most of the time, manual frees are just noise--this observation is the entire reason behind destructors.

[+] sph|3 years ago|reply
> More concerning is that un-named parameters are a compiler error

I've been ranting about it many times. Most recently: https://news.ycombinator.com/item?id=32145520

There is an upstream issue about it where we should probably get our voices heard, it's encouraging to see many people in that thread that are opposed to that change, but it doesn't seem the core devs are open to considering any alternative, rather they just hope we can learn to live with it.

https://github.com/ziglang/zig/issues/335

This is by far my biggest annoyance with Go, more so than writing if err != nil.

I feel I write code in a different way than other people. Some are very slow, thoughtful and methodical in writing code, while I tend to experiment, throwing stuff at the wall and iterating quickly, and only after going back to polish and refactor. Stopping every iteration during my experimentation phase to lint my code because the compiler is pedantic and stubborn just slows me down immensely and turns me off a language.

EDIT: went and shared my criticism upstream, in a constructive and reasoned manner, I hope. My quixotic fight against unused variables being errors carries on.

[+] peteradio|3 years ago|reply
> More concerning is that un-named parameters are a compiler error and this cannot be adjusted.

Would you be willing to expand this a bit? This would save you from giving a dummy name in a function?

[+] Kukumber|3 years ago|reply
My problems with Zig:

- the language ergonomics sucks

- syntax to play with arrays sucks (zeroing for example)

- lack of operator overloading for my math types

- too many repetition and casting, the compiler is not smart at all

- slow build speed

Things i love:

- build system, all in zig

- comptime

- module is basically a struct, so you can wrap your stuff in a file and import it as a struct, lovely

- the language remains simple enough to pickup, learn and to build any kind of software, it is enabler

Overall it's way too rigid, i miss the fluidity and liberty of C

It'll find its niche, it'll serve as good build system, but it definitely not a good contender for a C alternative

I couldn't care less about the illusion of memory safety with rust, chasing that language is a waste of time imo, and it's very dangerous, we'll see ton of new developers thinking their software is safe because the borrow checker didn't complain

[+] SubjectToChange|3 years ago|reply
> ... and it's very dangerous, we'll see ton of new developers thinking their software is safe because the borrow checker didn't complain

Would new developers be capable of writing secure C?

[+] agentultra|3 years ago|reply
Another thing which makes Zig interesting is it’s approach to allocation, making a failure to allocate memory a catchable error, and enabling developers to easily assign their own allocators.
[+] kaba0|3 years ago|reply
How can it guarantee that the OS doesn’t just lie about having allocated that space? As far as I know they are unallocated until a write to a given page (by default on Linux at least), and thus any write could potentially fault.

Unless it zeros every page it allocated, I don’t see it being able to defend against it in practice.

[+] vitiral|3 years ago|reply
Good writeup. Also I enjoyed your podcast back in the day!

My current thinking is that if you want to make a "small" language with anywhere near the guarantees of rust you need to make the features smaller too. A good start is cooperative multitasking, aka basically the async model, to radically simplify concurrency. Communication between processes must then be done with channels. Another is memory allocators, I think arenas are a good start, and I'll have to look deeper into Zigs approach.

[+] chriskrycho|3 years ago|reply
I think one of the possibly-good moves Zig makes, similarly, is using `comptime` for generic types. I don’t have a good sense of how that interacts with parametricity and ability to constrain those (and I suspect that’s an important question!) but it’s an interesting example of a possible trade off that lets the language size space.

(And: thanks!)

[+] rektide|3 years ago|reply
It sounds like aggitation excerpted so, but the write up does a wonderful job setting up for it, making this stunner of a line not seem so bad:

> For many C developers looking to upgrade their language, Rust looks a lot like a better C++, not a better C.

What a line!

The whats-included/what's-not takes me back to one of our legendary/epic (and at 9000 words, epic in length) posts, one I love to cite, Larry Wall's Perl, the first postmoderm computimg language[1]. A cut up early & favorite section:

> When I started designing Perl, I explicitly set out to deconstruct all the computer languages I knew and recombine or reconstruct them in a different way, because there were many things I liked about other languages, and many things I disliked. I lovingly reused features from many languages... To the extent that Perl rules rather than sucks, it's because the various features of these languages ruled rather than sucked.

> But note something important here. I left behind more than I took. A lot more. In modern terms, there was a lot of stuff that sucked. Now, on the feature set issue, Perl is always getting a lot of bad press... I think people who give bad press to Perl's feature set should have more angst about their reporting.

> I picked the feature set of Perl because I thought they were cool features. I left the other ones behind because I thought they sucked.

It's silly & basic plainly said like this, but the post goes on & on about finding creative use & also at length about deciding to leave things behind. Walls postmodernism is infectious. And this element of pruning, pairing down, is one that seems like an axis where elegance & grace can often take root & grow in todays busy, complicated world where so very much has accrued & accreted.

[1] http://www.wall.org/~larry/pm.html

[+] baby|3 years ago|reply
Reading this, I can totally see why I fell in love with Golang. The language is so dead simple that it's generally a pleasure to read any codebase, and very fast to learn/write.

That being said I write mostly in Rust these days and really like it too. There's definitely a number of issues in Golang that I wish they would address (sum types for example)

[+] kuon|3 years ago|reply
I am working with zig for embed code and it works well. It's mental model is easier than rust and it's easy to use static memory with std lib.

Also I had a project where I could not get cross compilation to work and compiling on the system itself was too slow in rust.

As I said earlier, both language can thrive and they both have a place in my toolbox.

[+] SV_BubbleTime|3 years ago|reply
How is it looking on embedded?

The real make or break for me is debugging / GDB. I’ve assumed that a debugger will be able to point to and step around native Zig code, now or eventually. But I wonder how it would work with C code you bring in? If that could be debugged seamlessly along with Zig code, that would really be something.

[+] jjtheblunt|3 years ago|reply
How much, of what is exposed as the complexity of a language, could be realized in the form of sequences of optimizing compiler passes, perhaps automatic or perhaps flag-driven, such that the programmer user experience remains clean-ish yet the sophistication of generated code is on par with a language like Rust?

I don't know the answer, but I find it a curious question.

(And are SBCL internal compilation optimizations an example of this idea?)

[+] bmitc|3 years ago|reply
I don't know much about Zig, but it shares a problem with Rust in that neither have a built-in REPL.

I'd like to learn Rust, but every time I try to, I am a bit overwhelmed by its complexity, both in syntax and overall feature set.

[+] throwaway17_17|3 years ago|reply
Do you mean you want an interactive environment to just write small code samples while learning? Or do you want to do your development after learning in a REPL? I think those are two very different goals.

As to Zig and Rust’s lack of REPL, they are both ahead of time compiled to executable languages. It is not super common for REPLs to be developed with any real frequency or faithfulness. (this is a little different in the functional world for some reason, Haskell, ML, etc have very thorough REPLs, and Koka’s REPL is great).

[+] bobbylarrybobby|3 years ago|reply
Rust doesn't have a repl (well it kind of does: the rust compiler slack bot that runs code you ask it to...), but if you use rust-analyzer the feedback cycle is just as fast. There's also https://play.rust-lang.org/ for testing short bits of code in a persistent editor.
[+] codazoda|3 years ago|reply
Interesting perspective. I’ve never used a REPL much. I did a bit of commercial Python and rarely used it there and I built my career on PHP, which kinda has one, but not a very usable one. I found the REPL to be a distraction. I just want to write code in my favorite text editor and then interpret or compile it.

I’m a bit old school, I realize.

[+] zozbot234|3 years ago|reply
The evcxr project https://github.com/google/evcxr is implementing what amounts to an experimental Rust REPL. (Though there's inherently something a bit weird about a REPL for C/C++-like languages, where the phase separation between compile- and run-time is so inherent to the programming model.)
[+] the__alchemist|3 years ago|reply
> a C developer might say. “But Rust is still a very large language, and only growing larger over time.” The C developer would be right.

Nice article. As someone who uses Rust on embedded, this is a concern I share - especially regarding async/await, which this article mentions specifically. I see my (and for others of a like mind) path forward is using an explicitly-defined-at-project-level subset of Rust... In the vein of what we see in C++. This use of a dialect has drawbacks for newcomers to a code base, but I prefer it to the alternative of not mitigating the downsides of a large language.

Perhaps this prediction won't turn out to be true, and the Rust language will slow its expansion.

[+] eyelidlessness|3 years ago|reply
I’ve only dabbled in Rust, I’ve read about Zig with earnest interest but no bandwidth to even dabble. My primary experience is with higher level languages. It’s quite possible my intuition here is very wrong, but I’m sharing it because my experience with Rust’s lifetimes felt so awkwardly unnecessary to me.

Lifetimes for memory make sense if you might modify memory. What if you don’t? My sense of a “smaller Rust” from my time exploring it was “why does everything assume it has a longer lifetime if I’m never going to access it again, if I’m never going to grant access to any other function, as soon as my function exits?”

I’m coming from a functional programming perspective, which I thought I’d found when I started with Rust. But it seemed to want to guard me from things I wasn’t even trying to do, in anticipation that in some unrelated part of the codebase I’d suddenly abandon all of the values I’d been respecting and start interrogating into their bits.

What if the “smaller Rust” is just “Rust with lexically scoped lifetimes unless you say otherwise”? I can imagine a borrow checker that defaults to the generally FP semantics of Rust’s syntax, rather than defaulting to the generally DSL-over-machine-code that’s typical of low level languages. I’m not sure what the language and implementation trade offs would be, but my instinct with Rust is that it would be simpler for most use cases, and not much more complex for the cases closest to C.

[+] scoutt|3 years ago|reply
I liked the article, and as an outsider to the discussion (I do embedded C for a living, and C++ as in "C with classes") I might add:

What I've seen so far is that Rust tries to lure C developers with a sort-of "memory-management shaming". I've even been called "old curmudgeon" here in HN for not showing interest in Rust, and not using it right now. I think if hear one more time that "70% of bugs are memory bugs; here is the link" I'm going to explode. For which I answer: "My applications have a button and a display, what exploits are you talking about?".

Spoiler alert: "memory-management shaming" doesn't stick with us. C is vast and has tens of millions of applications. Not every project is wired to Ethernet, BT or WiFi. If there is a bug, it might be hard to find, but that's it. Hey, there is people that even pays you to solve problems you've generated yourself. What's better than that?

Luring C developers is about something else and Rust doesn't get it yet. At the same time Rust tries also to lure millions of high-level languages developers with features like async-await, super clever one-liners, package management, etc., which personally as a C developer, I don't really care.

You can't make everybody happy. Make happy either C developers or JS developers. Pick one.

Another note: even if the language it's been there for a while, I often see "hey! I've built a build-essentials replacement! It only works like the 20% of it". You go to see the repo and it's been idling for the last 6 months.

So even the Rust's momentum is already starting to decay, there are really just a few of top "99% complete" reference projects. What does it means?

Zig on the other side, shows itself as a more humble language, with simpler syntax. I don't really like the syntax but it's not a big deal. Zig has, or at least, it users don't show bigger expectations. It's taking a careful and slow road and I like that very much.

That said I'm following both languages very closely. I only hope Zig doesn't become as bloated as C++ and Rust today, to be really in that sweet spot I'd like for embedded.

[+] rank0|3 years ago|reply
Anyone looking for a pleasant systems language check out Nim.

It’s the most fun I’ve had programming in a long time!

[+] v3ss0n|3 years ago|reply
Why all the new languages aren't white space based lang like Python ? Why they still need braces , braces are always hard to read the code and all modern code editor can work well with white-space based languages .

A native , non inerpreted , high performance whitespaced lang with memory safety , as simple as python would rule .

[+] fdsafdsfdsa|3 years ago|reply
We get that Zig doesn't have memory safe features. How much of a big deal is that anyway - what proportion of issues are caused by memory safety errors? And as an aside - how many Rust codebases use unsafe code?

(I don't know the answers to these - I'm a humble C programmer who intends to look at Zig soon).

[+] jillesvangurp|3 years ago|reply
I work with garbage collected languages all the time. Do you know how much time I spend tuning garbage collection and worrying about its performance? None whatsoever. Honestly, it's not a thing and it's mostly fine.

GC mostly just works really well. Occasionally you get some poor performance and then you find that you are doing something silly and then you fix it and move on. Or you throw more hardware at the problem.

GC has a bad reputation but the reality is that there is a lot of software being written with languages that aren't exactly famous for even having a particularly good garbage collector. Python, ruby, go, etc. They are alright but certainly nowhere near best in class when it comes to garbage collection. If that matters to you, you can pick python and ruby implementations that have way better performance than the default implementations provide. But the thing is, it does not matter. It's genuinely not a problem for people using those languages.

I\ve used each of those languages and also use Kotlin both on the JVM and in the browser. So, you'd think I spend a lot of time obsessing about what the javascript garbage collector does in the browser or how to tune the jvm? Nope. I just let it do its thing. We have no garbage collect related issues. So why spend time on it?

My observation is that engineers love talking about optimization but rarely realize how expensive they are relative to just throwing more hardware at a problem. And the thing is, some modest hardware goes a long way these days. We run our Spring/Kotlin JVM servers on cheap vms in Google cloud and in another data center using openstack. 2GB and one VCPU. About 25$ per month. That's around 10 minutes of my time at my freelance rate. Those are European rates, not Silicon Valley rates. Those are more like 3-5 minutes. We could go cheaper and I'm pretty sure I can make it run with half an GB if I work at the problem. But the savings are negligible and I like a little safety margin. We have many issues but our hosting bills are pretty awesome. Cutting them in half is literally not worth more than 1-2 hours of my time per month.

I think it's great that C/C++ are getting some competition from modern languages now. Rust has a pretty innovative borrowing mechanism and it seems to genuinely be better at certain things that have been the exclusive domain for heavily optimized C/C++ systems for decades. That's great. Zig seems like the more reasonable choice for people that just want something simple that works that isn't ancient and awkward like C but gets you ballpark in the same league in terms of performance. I learned C a long time ago and I love Linux. But the never ending exploits and security problems are a thing that I just don't need in my own projects. Having a garbage collector and some other safety has a tiny cost but eliminates whole classes of bugs and exploits. Completely worth it IMHO.

[+] Nomentatus|3 years ago|reply
For a couple of years, I’ve been thinking about whether there could be a simpler language that gets rendered into safe Rust the way Nim is translated into C and compiled as C. I’ve concluded that it is possible, but only if there’s a substantial chunk of AI sitting “in between” that analyses the code you’re writing in the simpler language and queries you, the coder, from time to time.

I’m not sure how coherent I can be describing what I have in mind, but for example: let’s say you’re happily typing and the AI chimes in to say to the coder: “Hey, it looks to me like you may be assuming, in what you’ve written so far, that your process A will always end before your process B. Maybe - maybe - in the real world that’s so. But I can tell you that logically it ain’t so. What Rust code do you want me to write, here: 1) one that just goes from your process A to your process C whether or not your parallel process B has finished or not, or 2) Rust code where B always waits for A, A always waits for B, or both wait for each other, or 3) unsafe Rust code that leaves this possible race condition intact ‘cause your sure- you’re willing to bet the company - that not just this version of the program, but all possible future modifications of it, are never gonna encounter a real-world instance of B being delayed? And do you want any telemetry (asserts) (”fries”) with that?”

Exactly how the AI can borrow check without you doing much if any borrow checking is maybe harder to describe; but might involve informing you that the code you’ve written so far allows simultaneous updating of a variable, and what would you like to do about that, if anything? Would you like some telemetry to let you know if such nonsense begins to happen during a run? (Fleshing this out may be non-trivial.)

The AI would also bring stuff like badly formed loops allowing buffer overwrites to your attention, of course.

I’m quite sure that creating such an AI programming helper/translator into Rust would be difficult. But I suspect it’s possible, and I want one. I’m retired, I won’t be building it.

See verdagon's very interesting comment here (and the replies to that) for what's already being done at least a little along the same lines.

[+] dleslie|3 years ago|reply
I'm a decades-long C hacker and I'm not sure why I should use Zig anywhere that I use C. What's the killer feature/reason?
[+] Laremere|3 years ago|reply
C has an enormous weight to it. If you've been carrying it for decades, you are likely somewhere between being so used to carrying it it's hard to notice the burden, and being so at ease with carrying it that it's not actually a burden. Imo, Zig doesn't have /a/ killer feature. Instead it has hundreds of small design choices made with the insight of decades of programing language evolution, along with a few clever ideas on its own.

I would say it's well on the way to becoming the best language for giving you control as a programmer over the computer. Compared to say Rust focusing on safety first, execution speed second, ergonomics third; Or Go on maintainable systems at large corp scale.

To list some specific examples:

   - No headers.
   - No complex build and linkage systems.
   - Fast compilation (and no explosion of compile time as headers import headers.)
   - A small and distinct set of fundamental types, with true enums, unions, and arbitrary size integers.
   - Code formatting, which is a feature that feels kind of invisible, but means arbitrary code you look at will be formatted in a familiar way.  A subtle but powerful difference.
   - It doesn't try to remove undefined behavior.  Instead it does a really good job of catching you hitting it when building in a development version.  Imo, often code wrote simply will have undefined behavior that is meaningless because it will never be called with that behavior.  It's fine to code that way in C until you accidentally hit it and have a hell of a time figuring out why something isn't working.
[+] verdagon|3 years ago|reply
A few big benefits off the top of my head:

* A concurrency mechanism that's very easy to use, because it doesn't have the function coloring problem of async/await.

* Extra assistance with memory safety, via its "release-safe" mode. Not a silver bullet, but it does help!

* Good tooling; zig cc can cross-compile from any major OS to any major OS.

* Comptime, a pretty brilliant system that does what generics does for other languages, with a fraction of the complexity.

[+] AndyKelley|3 years ago|reply
std.ArrayList

std.HashMap

std.ArrayHashMap

std.MultiArrayList

std.heap.ArenaAllocator

defer/errdefer, try, catch

Debug mode: stack traces, safety checks, segfault handler, error return tracing, valgrind integration, undefined bytes set to 0xAA, GeneralPurposeAllocator finds leaks, double frees, and use-after-frees

Comptime instead of macros

Unit testing

[+] syntheweave|3 years ago|reply
The killer feature of Zig is polish - not yet in implementation(teething issues still abound if one tries to take it into production) but definitely in design. It goes down the list of every language wart or make-do tooling situation in C and addresses it with a reasonably specified and generalized feature, without making the language much bigger(if it is at all - it's not a big language spec). It actively works on some really grody systems-level problems with building binaries that most languages will address with "compiles to C" and C itself addresses with "fight the build system" - Zig aims to be a one-stop shop that clarifies this process. And it integrates C code compilation into its build system, so existing projects can be migrated.
[+] cturtle|3 years ago|reply
Among all the other suggestions, I appreciate the refinement to the type system that zig has over c. Like bools and ints are distinct types, built in slice types to associate a pointer and length, arrays have a length, well-defined integer sizes (i32 for example), optional, errors, etc. it’s little things like that which make a language much easier to use in the long run.
[+] ArrayBoundCheck|3 years ago|reply
From what I hear 1. No headers (you can use headers to import C functions. None needed for other zig functions). 2. defer 3. Comptime