Side question as I am following zig only losely and do Go Programming:
Zig has the feature that you can drop in your allocator from the caller. Now with 0.16 you also "bring your own IO" implementation with you.
And for my understanding this looks like the pattern Go uses with its Context package, where you pass in transitive data, cancellation signals and timers to for example stop an SQL query in server B, since a user canceled a web request in their browser before hitting server A, whilst all elements delegate the Context.
Then yesterday was total unrelated article about NUMA architecture, and I remember somewhere that the creator of Erlang mentioned (Joe Armstrong) that you cannot get around physics and it takes time to call a function between servers, therefore so not try to hide the latency between the calls.
And now to my question:
Would that in any way make sense for zig to go even more in this direction, where you pass in your allocator, IO, but now with something similar to Google Go context, but have it even more fine grained?
So that your functions could actually in their interface expose somehow the time in between CPU cores (NUMA) up to the request cancellation as Google go context is used for timeout signals, cancellation signals.
Also probably making time an external dependency as well.
So in essence , every function would be treated as a remote procedure calls, whereas remote would mean: "other cpu", other server/service
not really sure what you're asking. but time is now part of the io interface, so you can pretty easily write your own io implementation that just stubs out to the stdlib's default io content and has custom time functions if you want to try something funky. This is pretty close to what you are asking for (and in terms of functionality, equivalent). I say go for it and see what happens, report back!
I really love everything about zig except the language itself. The governance, the culture, all of it seem really cool, but reading https://ziglang.org/learn/why_zig_rust_d_cpp/ I still don't get _why_ I would use it. To an untrained eye, it seems like go, but with manual allocation. Or an imperative-only rust. Like it has some features of all the languages it competes with, but not the ones that would make me reach for them.
What do people use zig for, and why zig and not one of the others?
I have the same feeling about Zig. In this interview [1], Andrew Kelley, creator of Zig, explains a lot of the features of the language; compares it against c, rust, go; and explains why he created the language. According to him, the killer feature of zig is the tool chain (compiler, linker, build system) since it has no dependencies. So, it will work in any OS/target you choose.
It is a really interesting interview. However, Zig code is a bit hard for me to read.
> What do people use zig for, and why zig and not one of the others?
I'm the maintainer of zigler (https://zigler.hexdocs.pm/Zig.html), and I have my own pharma startup. I currently use zig in two contexts:
1) wraps a proprietary .so file that is used to communicate with a scientific (microscope) digital camera, in a nice BEAM-module-shaped interface. Sorry, code is private.
2) I have a vue.js component that does DNA editing, and one of the features is DNA sequence alignment, and so I had claude write the smith-waterman lalign algorithm in zig, and it compiles to wasm, and this plus going from O(N^2) to O(N) dropped the runtime of an alignment from 30s to a few hundred ms, in both cases so much better than ~5m using a web SAAS, good enough that I can render alignments on-demand, and I don't have to do a storage layer for alignments.
Two sequences may be aligned by right-clicking a sequence name when a sequence is loaded, it will align the two sequences (you'll have to create a second sequence as it forbids aligning a sequence with itself).
Why zig? Because it just makes things like cross-compilation easier (microscope is mounted on a elixir nerves deployment!), and has less footguns, and doesn't hide away things you might care about. Most of the things i build with zig don't really have a concern about memory safety, or have such trivial memory patterns that it's easy to verify by eye that they're memory safe.
Can you give more details about using zig along with elixir?
> microscope is mounted on a elixir nerves deployment!
What do you mean? I imagine that there is an Elixir application running on an embedded system and maybe it relies on an external binary application (compiled using zig). If so, how do you manage the communication between them?
I think this blog post has a great description of the "Modern C" niche Zig fills: https://vfoley.xyz/hare/. I tend to think of Zig in this way. If you found yourself reaching for C, you could instead reach for Zig. You'd get optionals instead of null pointers, comptime instead of macros, a real facility for handling errors, etc. It's like C but with some of the sharp edges sanded off.
Try reading zig code. For me its much more readable than the other languages, and does not suffer the fact go doesnt have language level errors. Local allocators are very useful and if you dont think so, perhaps you havent dwelved too deeply into systems programming or the language isnt targeted for you.
I get the usefulness of allocators, I just don't see them as useful enough where I'd pick zig over another established systems programming language. Do you have an example?
since zig anoints an allocator interface in its stdlib, your (and the stdlib's) data structures which use allocators can be trivially reused across different allocation strategies without rewriting code; and very likely (not guaranteed ofc) if you bring in someone else's code they will cleave to convention.
I think Zig would do better than Go at things like kernels, drivers, game engines, lower level sorts of things. Edited to add the obvious: SPIR-V, for instance.
Of course there’s lots of programming that can afford to pay for GC side effects, if there weren’t we wouldn’t have invented GC, but it’s a little less universal, a little less ‘system’.
For me, I came to Zig after horrible cross-platform experiences led me to try going all the way back to C and I found that I was spending way too much time learning to deal with accidental complexity instead of essential complexity. (Respect to the C masters but I failed to adapt.)
I think one of the selling points is that the language does not come to your way and allows unsafe constructs. So, I think the target audience is roughly at C and C++ users.
C is over 50 years old, but it is still more or less the lingua franca of computing. The world benefits from having "C with some improvements from 50 years of learning". The world also benefits from having featureful languages that are a huge divergence from C, but it also just needs a language that provides a thin cross-hardware abstraction over the asm layer and some conveniences over writing raw asm. We don't need every language to be massively featureful, and we hopefully won't all have to reach for C for the rest of human civilization when we need a language that isn't massively featureful.
Zig has the feature that you can drop in your allocator from the caller. Now with 0.16 you also "bring your own IO" implementation with you.
And for my understanding this looks like the pattern Go uses with its Context package, where you pass in transitive data, cancellation signals and timers to for example stop an SQL query in server B, since a user canceled a web request in their browser before hitting server A, whilst all elements delegate the Context.
Then yesterday was total unrelated article about NUMA architecture, and I remember somewhere that the creator of Erlang mentioned (Joe Armstrong) that you cannot get around physics and it takes time to call a function between servers, therefore so not try to hide the latency between the calls.
And now to my question:
Would that in any way make sense for zig to go even more in this direction, where you pass in your allocator, IO, but now with something similar to Google Go context, but have it even more fine grained?
So that your functions could actually in their interface expose somehow the time in between CPU cores (NUMA) up to the request cancellation as Google go context is used for timeout signals, cancellation signals.
Also probably making time an external dependency as well.
So in essence , every function would be treated as a remote procedure calls, whereas remote would mean: "other cpu", other server/service
It is a really interesting interview. However, Zig code is a bit hard for me to read.
[1] https://www.youtube.com/watch?v=iqddnwKF8HQ&t=10s
I'm the maintainer of zigler (https://zigler.hexdocs.pm/Zig.html), and I have my own pharma startup. I currently use zig in two contexts:
1) wraps a proprietary .so file that is used to communicate with a scientific (microscope) digital camera, in a nice BEAM-module-shaped interface. Sorry, code is private.
2) I have a vue.js component that does DNA editing, and one of the features is DNA sequence alignment, and so I had claude write the smith-waterman lalign algorithm in zig, and it compiles to wasm, and this plus going from O(N^2) to O(N) dropped the runtime of an alignment from 30s to a few hundred ms, in both cases so much better than ~5m using a web SAAS, good enough that I can render alignments on-demand, and I don't have to do a storage layer for alignments.
https://github.com/Vidala-Labs/opengenepool/tree/master/src/...
you can play with it at:
https://opengenepool.vidalalabs.com
Two sequences may be aligned by right-clicking a sequence name when a sequence is loaded, it will align the two sequences (you'll have to create a second sequence as it forbids aligning a sequence with itself).
Why zig? Because it just makes things like cross-compilation easier (microscope is mounted on a elixir nerves deployment!), and has less footguns, and doesn't hide away things you might care about. Most of the things i build with zig don't really have a concern about memory safety, or have such trivial memory patterns that it's easy to verify by eye that they're memory safe.
> microscope is mounted on a elixir nerves deployment!
What do you mean? I imagine that there is an Elixir application running on an embedded system and maybe it relies on an external binary application (compiled using zig). If so, how do you manage the communication between them?
https://www.erlang.org/docs/25/man/erts_alloc.html
jvm has at least 5:
https://github.com/openjdk/jdk/blob/master/src/hotspot/share...
postgres has at least 8:
https://github.com/postgres/postgres/blob/master/src/backend...
since zig anoints an allocator interface in its stdlib, your (and the stdlib's) data structures which use allocators can be trivially reused across different allocation strategies without rewriting code; and very likely (not guaranteed ofc) if you bring in someone else's code they will cleave to convention.
Of course there’s lots of programming that can afford to pay for GC side effects, if there weren’t we wouldn’t have invented GC, but it’s a little less universal, a little less ‘system’.
For me, I came to Zig after horrible cross-platform experiences led me to try going all the way back to C and I found that I was spending way too much time learning to deal with accidental complexity instead of essential complexity. (Respect to the C masters but I failed to adapt.)
I think one of the selling points is that the language does not come to your way and allows unsafe constructs. So, I think the target audience is roughly at C and C++ users.