Live data from Hacker News

Failing to Learn Zig via Advent of Code

forrestthewoods.com

271–280 of 338 posts

Re: Failing to Learn Zig via Advent of Code

#271
post #269

Earlier quoted context omitted.

> Modular arithmetic is perfectly well-defined. Yes (and thanks for the link!), I was in fact thinking more of this non-UB case (not signed overflow UB) as an example of where it's clearly defined as wraparound but can be chained into an exploit nevertheless, not technically UB but a vulnerability nevertheless. Not all exploits bother to go as far as a UAF. Unchecked arithmetic can be low hanging fruit. > That didn't…

Checked arithmetic is a much bigger performance hit than most people expect. It means that every arithmetic operation is potentially a branch/jump instruction. This wrecks a lot of pipelining/out-of-order-execution schemes. I once worked on an exotic architecture where the integer types had a "NaN" value just like floating point numbers do; it had both modular and checked arithmetic, but the checked versions would re…

> Checked arithmetic is a much bigger performance hit than most people expect.

You're right about the branching cost. I believe there's a better way to solve that than disabling checked arithmetic everywhere.

This comes out of something I learned working on TigerBeetle [1], a new distributed database that can process a million financial transactions per second.

We differentiate between the control plane (where we want crystal clear control flow and literally thousands of assertions, see NASA's "The Power of 10: Rules for Developing Safety-Critical Code") and the data plane (where the loops are hot).

There are few places where we wouldn't want checked arithmetic in TigerBeetle enabled by default. However, where the branch mispredict cost relative to the amount of data being checked is too high, Zig enables us to mark the block scope as ReleaseFast to disable checked arithmetic.

> It also had 37-bit integers. Yes, 37-bit. Fun times.

Wow, fun times indeed! We just disabled 32-bit support for TigerBeetle because it was getting too hard to reason about padding. I can't imagine 37-bit, LOL!

[1] https://www.tigerbeetle.com

Re: Failing to Learn Zig via Advent of Code

#272
post #177

Earlier quoted context omitted.

Zig already does this with its current documentation and example code.

I saw that after reading further. Loris (I don't remember his user name here) also said he plans on rewriting it from scratch on Twitch. I may tune in just to see how his mind works. :D

Well worth doing, I've learned a lot about coding from Loris.

Re: Failing to Learn Zig via Advent of Code

#273
post #169

As a seasoned Zig programmer, this is good information, though painful to read. A lot of the problems seem to be from a fundamental misunderstanding of Zig's philosophy and very basic things about how the language works. Possibly Zig needs more emphasis on those things in its documentation. I also have to wonder about a fundamental misalignment of thinking when someone says downloading and replacing a single .exe is…

I have a feeling that Zig is sufficiently different to most other languages in the space that developing a mental model for the way things are supposed to fit together is something that involves "aha" moments - the sort that are tricky to produce for everybody via a single piece of documentation because the thing that makes it snap together in a particular person's head varies widely between people. Similar to the pr…

When I saw the first line of some Zig code, it was unusual so I thought about it and got an inkling of the idea behind it and its power:

const std = @import("std");

When I saw the second line and subsequent similar lines, I realized it was effing brilliant:

const os = std.os;

std and os here are names bound to types ... and you can have type variables and do compile-time manipulation and construction of types. This is confirmed in the manual when it talks about generic types being the return values of functions executed at compile time that take types (and/or other comptime values) as arguments -- while C++ templates are purportedly Turing complete, this is far more powerful in practice because it's vastly easier and more straightforward. Looking at code in the library like MultiArrayList--which implements AoS (array of structures) in the library rather than in the language--further confirms this.

So what's going on with those `std` and `os` bindings? The answer is given at the beginning of the Zig Language Reference (https://ziglang.org/documentation/master/) (which the OP apparently didn't read since it has a Hello World program that is an example of how to print): "The @import("std") function call creates a structure that represents the Zig Standard Library". So essentially, every source file represents an anonymous struct (all Zig structs are anonymous), the members of which are the top level declarations in the file--or rather, @import(filename) presents the file as such a struct, which can be assigned to a type variable like `std`. And `std.os` is in turn a type variable whose value is @import("os.zig") ... except that the actual value of `std.os` is computed based on the target machine. By turning files into comptime data structures containing all of the file's top level declarations, and having Zig code executable at comptime, immense power is achieved and one of the consequences of this is that zig running on any host is a complete cross compiler that can generate code for any target, using an appropriate target-specific version of the library. And it only took me a little bit of reading of docs and code to get my "aha" about how this works.

Re: Failing to Learn Zig via Advent of Code

#274

Earlier quoted context omitted.

> My big problem with Zig is that Andrew Kelley is promising a lot of features, but doesn't really deliver much. Have you, like, seen the release notes for 0.9.0? https://ziglang.org/download/0.9.0/release-notes.html > Zig still can't proper handle UTF-8 strings [1] in 2022 There's plenty of discussion on the subject in basically every HN thread about Zig: the stdlib has some utf8 and wtf validation code, ziglyph imp…

Why does something as basic as uppercasing a string or decoding latin1 require a third-party library? I would expect that to be part of stdlib in any language. Also, why does that third-party library come with its own string implementation? What if my dependency X uses zigstr but dependency Y prefers zig-string https://github.com/JakubSzark/zig-string >? Basically all languages designed in the past 30 years have at l…

correct-for-BMP-but-not-otherwise is simply a bug (and cultural chauvinism). And almost all of such implementations aren't correct-for-BMP because uppercasing Unicode is far from "basic".

Re: Failing to Learn Zig via Advent of Code

#275
post #171

Earlier quoted context omitted.

It's an open question [1] along with other safety checks both comptime and runtime [2]. The issue here is a balance of keeping language complexity low while providing safety at the same time and not depriving users of control when they know better than the type checker/lifetime analysis. [1]: https://github.com/ziglang/zig/issues/782 [2]: https://github.com/ziglang/zig/issues/2301

This is such a squishy value proposition, which is why people aren't taking Zig seriously. Rust's value proposition is simple: no GC and no undefined behavior. Period. Nothing else has that.

I don't know, people like Mitchell Hashimoto and Tobi Lütke are taking Zig seriously for systems programming. Coil are also investing in writing a new distributed financial database for Zig—considering the trajectory of the language and the lifetime of our project, it made sense.

Of course the swell is early, but waves are what technology is about, and the surfers are there and paddling out. It's a great time to be getting involved, especially for greenfield projects that have some time in themselves to reach stability and don't want to pay a language compiler/complexity tax for the rest of the project's lifetime.

You could also throw a dart blindfolded into the Zig community and be pretty sure to hit some seriously talented programmers to learn from. If you're investing in a deep understanding of the language now, I'm pretty sure it will pay off down the line.

Re: Failing to Learn Zig via Advent of Code

#276
post #70

My big problem with Zig is that Andrew Kelley is promising a lot of features, but doesn't really deliver much. Zig still can't proper handle UTF-8 strings [1] in 2022, which is kind of unfortunate, because it's a `requirement`. In a `recent` interview[2], he claims that Zig is faster than C and Rust, but he refers to extremely short benchmarking that has almost no value in the real world. At least Rust, as blamed and…

> My big problem with Zig is that Andrew Kelley is promising a lot of features, but doesn't really deliver much.

My biggest problem with your comment is that it is completely and utterly false.

>At least Rust, as blamed and loved as it is, delivered a stable compiler

After MANY years and numerous complete redesigns.

Re: Failing to Learn Zig via Advent of Code

#277
post #77

Earlier quoted context omitted.

Rust was started in 2006. [1] Zig was started in 2015. [2] [1] https://en.wikipedia.org/wiki/Rust_(programming_language) [2] https://en.wikipedia.org/wiki/Zig_(programming_language)

The language called "Rust" prior to 2013 is a completely different language from what people today know as "Rust". That language had a garbage collector, mutable aliasing, and no borrow checker (the three most unique features of today's Rust), and was basically "golang with different syntax": http://smallcultfollowing.com/babysteps/blog/2012/11/18/imag... The whole language got rebooted shortly after the blog post ab…

What matters is time from initial inception.

Re: Failing to Learn Zig via Advent of Code

#278
post #251
post #158

Earlier quoted context omitted.

Yes, I also had the impression Rust is a C replacement.

Rust's purpose, its whole reason to exist, is to displace C. Rust will unavoidably fail in that, because anybody still using C is not willing to learn anything else: anybody willing to move on from C already did, long ago. Rust is already approaching C++ in complexity, surpassing it in some places; and also in expressive power, but not surpassing it anywhere yet. If Rust does not end up fizzling (which is still very…

[deleted]

Re: Failing to Learn Zig via Advent of Code

#279
post #251
post #158

Earlier quoted context omitted.

Yes, I also had the impression Rust is a C replacement.

Rust's purpose, its whole reason to exist, is to displace C. Rust will unavoidably fail in that, because anybody still using C is not willing to learn anything else: anybody willing to move on from C already did, long ago. Rust is already approaching C++ in complexity, surpassing it in some places; and also in expressive power, but not surpassing it anywhere yet. If Rust does not end up fizzling (which is still very…

Even if the only success story for Rust would be mainstream adoption of lifetime checkers across languages to some extent, that would already be a victory as it managed to change the baseline of language design across the industry.

A subject that now has become even regular presence at C++ conferences and considered a must have in static analysers roadmap by all major vendors.

Rust might fizzle out in a decade, and still leave such a mark in the industry.

Re: Failing to Learn Zig via Advent of Code

#280

Earlier quoted context omitted.

A potentially huge roadblock to better error messages is lack of generics and interfaces/traits/classes. The comptime machinery is really cool, but it gives the compiler much less information to work with for producing good errors. It'll be interesting to see how this plays out as the ecosystem grows.

> The comptime machinery is really cool, but it gives the compiler much less information to work with for producing good errors. Why do you think that's the case?

Because all the semantics for what are the valid parameters for types and other comptime operations are scattered throughout the code that is run at comptime. It's the same problem as with C++ template code, but perhaps worse. For instance, if you do a formatted print and pass an integer to a "{s}" descriptor, the std.fmt code calls @compileError with an informative message, then a dozen lines of stack trace are printed before a line that shows the source code line that invoked the print, and then yet another stack trace because std.fmt returns an error. And that's for std.fmt that is well behaved and calls @compileError when it should ... in many cases the error will be due to a type mismatch or invoking a non-existent member, etc.
Post reply on HN