4 ms·
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("s
by jibalt 5y ago
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/ 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.
- mst 5y agoNow I want somebody who understands both languages better than I do to write a comparison of how Zig and Nim's respective approaches to imports and comptime work.
- jibalt 5y agoNim is a far richer and higher level language that, like Zig, can run arbitrary code at comptime, but it also has templates and macros. But Zig does have a some things like "import a file imports a struct" which are unique to it and reflect its devotion to cross-compilation as a first class feature: every Zig compiler on every host can compile programs for every other host (at least within the Tier 1 support). Nim can't do that and I don't think any other language can. And its import mechanism is pretty standard, simply making names visible to the importing file or block; the names aren't organized into nested structs as in Zig.