Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The biggest quirk is arrays vs slices, their notation, and pointer types. Its a nightmare


The notation is very "compressed", that's for sure.

On the other hand, manipulating sequences of data and pointers of various kinds is one of the main things you do when programming, and concise notation (especially in a low level programming language) is akin to how mathematicians have concise notation for the most common objects they manipulate in their formulas.


Arrays vs slices seem to be pretty much the same as in Go, and the notation is completely straightforward: "ARRAY 100 OF INTEGER", except instead of "ARRAY" and "OF", the "[" and "]" are used — type constructor goes first, before its arguments, as it should be.

As for pointer types, they look reasonable but can't say much more.


One correction: Go slices also own their memory, so their equivalent would be Zig's `std.ArrayList`. Slices in Zig are just ptr+len, so you will have to manage the underlying memory separately. This makes sense for Zig since it's a lower-level language than Go.


> One correction: Go slices also own their memory

They both do and don’t, which is a major issue with the language.

If you create a slice from an array, it’ll use that array as backing buffer. Likewise if you reslice and existing slice.

But because it also has an arraylist interface (kinda, it’s a bad one) you can quite easily stomp on other slices using the same backing buffer.


Oh yes, I've had some quite hilarious (read: infuriating to debug) bugs because of that behaviour.

I imagine that's why almost everyone just use slices exclusively: you rarely if ever see "[SomeConstant]whatever { ... }" or even "[...]whatever { ... }" in Go codebases, it's almost always just "[]whatever { ... }": such literal slices have copy-on-append behaviour. And the syntax really nudges you into it which is nice.


> such literal slices have copy-on-append behaviour.

Only because literal slices default to cap == len (and a buffer of the same size). But if you create a sub-slice then all bets are off. That’s why some folks recommend always using a “full slice” if the result escapes:

    A[x:y:y]
This way the cap() is set to the same value as the len(), and append will always trigger a copy. Essentially a cheaper (but riskier) version of a defensive copy.


it's difficult, but they are there for a reason. Working through them helped me appreciate all of the different options that exist (and yes sentinel termination is sometimes better: https://lemire.me/blog/2020/09/03/sentinels-can-be-faster/)

If there's one thing that's a nightmare about how zig handles these is that sometimes coercion between array types is a bit hidden and the rules are not obvious, though their application in code is usually straightforward and you don't have to think about it too much (AFAICT it doesn't let you do the wrong thing)




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: