Fuck ZIG (and maybe low-level programming in general?)
I started lightly coding when I was like 14 - modifying HTML & CSS on myspace. My first real language was Java when I learned to develop Android when I was probably 19. I have since become extremely proficient in PHP and Javascript, decently proficient in Bash, and I've quite frankly forgotten all things Java. I'm 34 now.
Not long ago, I listened to a 2 hour long interview with the creator of Zig, a modern low-level programming language. It is still under-development. I guess it aims to do the same things C does, but ... suck slightly less and be slightly less prone to bugs & security vulnerabilities (though I know it doesn't go as far as Rust).
I liked the founder. I liked his anti-ai stance. I like learning new things. I like programming.
But this fucking language man, I just can't. I am out of patience for it, after about ... 8 hours or so, across 3 different days.
Early in the process, there were some ... things that were weird. And poorly documented. Like how do I declare a string? Normally, you don't have to provide a type, so it's just const alphabet = "abcdef....". But sometimes you do have to provide a type and then it's like const alphabet: []u8 = .... That's fine, okay, I can learn all this type stuff.
It isn't super well documented, but it's fine I can figure it out. There is a section of types, but all the language seems to care about is bytes and integers ... so there's not really any native type for strings/characters. And I don't really mind that. What I do mind is that the documentation doesn't just say "this is the type for strings".
My first major frustration came with just ... trying to read a file.
In PHP, I do this: $content = file_get_contents("/file/path");
In Zig, I had to peruse the standard documentation and find that to open a file, you need to reference std.Io.Dir.SOME_FUNCTION. Okay. No biggie, I just gotta learn the namespaces. But I find the function (readFile()), and you have to pass to it a Dir object, and an Io object. To make an Io object, you need to pass to it two fields: userdata which has the value ?*anyopaque. I had to do a bunch of web searching to figureout what anyopaque is, because it just isn't documented. And then the other field is a VTable, which is an object that also has to receive an Alignment object and .... jesus christ, you see my problem? I just want to read a file.
One of the main documentation references it gives has aa ... more approachable solution through std.fs.cwd().openDir(...). fs existed in 0.15, and I'm in 0.16 which now has io instead of fs. And then the openDir() function now requires the Io object as well as OpenFileOptions (which is documented, but not well). ... so I do a bunch more searching. I try several solutions that just literally don't run. And I land on this, which initialize a debug allocator, a threaded object, a Writer object, opens a file ... It's 42 lines of code (probably like 25 if you remove empty lines and comments) ... 20+ lines to READ THE CONTENT OF A FILE.
Well. I had actually been on zig 0.17 (the downloads page doesn't tell you NOT TO USE THE UNSTABLE MOST RECENT VERSION). I downgraded to 0.16. The API is basically the same, but when I re-install and re-init a new project directory, I see that the pre-provided main() function receives an argument: init: std.process.Init. And know what? init.io is the io object I was needing earlier.
So it turns out to read a file in zig, I just need to do this:
try std.Io.Dir.readFile(std.Io.Dir.cwd(), init.io, "src/php/string.txt", &buf);
Okay. Fine. Good. Figured it out. It should never be this hard to figure out how to do such fundamental things with your programming language. Reading/writing files is just ... fundamental, like I said.
I got over that hurdle. Moved on. And now I need to process the file line-by-line.
It's a little annoying, because again it is NOT WELL DOCUMENTED, but I figure out that the functions to find characters (like the newline character \n) is in std.mem. I figure out how to use these and a while loop, and okay it's late I'll come back tomorrow.
Well now TODAY is tomorrow. And I want to know "Is the first letter of this string a space character?"
AND GUESS WHAT
Finding out is hell. In PHP, I would do if (substr($string,0,1) == " ").... In zig, strings are arrays of bytes. So I thought if (line[0] == " ". But it turns out that line[0] refers to a BYTE, not to a character, so it returns a number. Further, if I want to loop over characters in the line, then instead of giving me characters, it gives me bytecodes. Numbers.
So I look again at the Zig Book, another primary reference material, to see how to iterate over characters in a string. You have to init a Uttf8View, then use that to create an Iterator, then loop over it in a WHILE loop using iterator.nextCodepointSlice(). But in zig 0.16, nextCodepointSlice() takes an argument, which is a Utf8Iterator. Is this iterator itself? Do I call it statically like std.unicode.Utf8Iterator.nextCodepointSlice(iterator_object)? I don't know. I don't care. I tried a couple things and the code just won't run. Won't compile.
And I could not, for the life of me, figure out how to just get the first character of the string.
I'm fucking done with this language dude. This was my first forray into low level and it was horrible. And I think it was more zig's fault than low-level's fault.
The worst part BY FAR is the bad documentation, the out-of-date documentation, and the failure of it to answer BASIC questions about how to do fundamental things. Reading and processing strings is so utterly important. You're making a brand new programming language. You should make it the easiest thing ever to do. But it's horrible. And it's not documented well. And where it is documented, the sample code literally doesn't work in the current version of zig.
I was interested in zig because I liked the developer of it, because I've long been interested in getting into some lower-level programming, because I wanted an excuse to try-again at an old project I abandoned awhile ago, and because I just felt like it.
I do not feel like it any more. This was a terrible experience. There were definitely things that were a little offputting, a little odd, that I'm fine with, that I know I would just need to learn. For example, printing a string is like: std.debug.print("{s}", .{alphabet}); It's weird. The .{variables} syntax is weird. Every .zig file is itself a STRUCT, which is similar to a class in PHP, though files in PHP are scripts, and classes must be defined with the class keyword. I didn't care for how importing works, but it's fine, definitely workable. All the low-level typestuff is something, but learnable, and I'm sure there are huge benefits performance-wise.
I liked how descriptive errors were when I tried to compile. The actual output was a bit overwhelming, just could be spaced or colored better, idk. But it was generally pretty good. Idk. It wasn't all bad. But the things I actually need to do felt practically impossible because they just weren't documented well, or because the API for them was far too cumbersome.
I don't know if I'll try another low-level lang. I would probably go for Rust. I don't want to use Go or any other language made by a huge conglomerate. I don't want the headache of C and its memory management. But right now, I'm just missing PHP's simplicity and ease-of-use and top-notch documentation.
I'll also re-iterate that Zig is UNDER DEVELOPMENT. It hasn't reached its 1.0 release yet. I don't know when it will. That certainly makes some of the problems more forgiveable, but it doesn't mean that I have the patience for them.
And I know some experienced devs will probably just be thinking "READ THE FUCKING MANUAL" and ... No. Actually no. I should not have to read 400 pages of a book to figure out how to read a string. No thank you. I want better, more approachable documentation. This just isn't for me.