If you have a few bucks per month to spare, consider chipping in. I'm hoping to have enough funds soon to hire a second full time developer.
Are there any concurrency constructs provided by the language yet? I'm just starting to learn how to do concurrency in lower-level langauges (with mutexes and spinlocks and stuff). I'm coming from the world of Python where my experience with concurrent state is limited to simple row-level locks and `with transaction.atomic():`.
An equivalent article to this would be awesome for Zig: https://begriffs.com/posts/2020-03-23-concurrent-programming...
Edit: I just found this announcement for async function support: https://ziglang.org/download/0.5.0/release-notes.html#Async-...
This area is still bleeding-edge experimental, but it's very promising.
I need to do a blog post on how async/await works in zig and event-based I/O. It's been a long time coming.
Grand bootstrapping plan [1] sounds really impressive but still WIP? Is there a commit or series of commits showing recent targets that got support?
On my RPi 4, 'uname -m -o' returns: armv7l GNU/Linux
Thanks!
I find it hard to believe that someone could be capable of writing a non-trivial program but not able to change their text editor settings to use \n.
> Compare this to downloading Clang, which has 380 MiB Linux-distribution-specific tarballs. Zig's Linux tarballs are fully statically linked, and therefore work correctly on all Linux distributions. The size difference here comes because the Clang tarball ships with more utilities than a C compiler, as well as pre-compiled static libraries for both LLVM and Clang. Zig does not ship with any pre-compiled libraries; instead it ships with source code, and builds what it needs on-the-fly.
Hot damn! You had me at Hello, World!
Even though it probably doesn't qualify this is pretty close a Canadian Cross, which for some reason is one of my favorite pieces of CS trivia. It's when you cross compile a cross compiler.
https://en.wikipedia.org/wiki/Cross_compiler#Canadian_Cross
> The term Canadian Cross came about because at the time that these issues were under discussion, Canada had three national political parties.
What are the three targets in this case? It simply isn’t relevant at all.
Being able to bootstrap FreeBSD/amd64, Linux/arm64, and actually commonly-used OS/ARCH combinations in a few minutes is just like a dream, but it is reality for modern language users.
It has manual memory management as well as garbage collection. You could call it hybrid memory management. You can manually delete GC objects, as well as allocate GC objects into manually allocated memory.
The Zig website says "The reference implementation uses LLVM as a backend for state of the art optimizations." However, LLVM is consistently 5% worse than the GCC toolchain at performance across multiple benchmarks. In contrast, GCC 9 and 10 officially support Dlang.
Help us update the GCC D compiler frontend to the latest DMD.
Help us merge the direct-interface-to-C++ into LLVM D Compiler main. https://github.com/Syniurge/Calypso
Help us port the standard library to WASM.
That is true, but it is ALSO true that LLVM is consistently 5% better than the GCC toolchain at performance across multiple benchmarks
I am really happy that someone is making the effort to steadily simplify systems programming rather than make it more complicated. Linux goes to such incredible lengths to be bug-for-bug backwards compatible, but then the complexities of all of our layers of libcs, shared libraries, libsystemd, dbus, etc cause unnecessary pain and breakage at every level. Furthermore, cross-compiling C code across different architectures on Linux is far harder than it needs to be. I have a feeling that there wouldn't be as much interest in the steady stream of sandboxes and virtual machines (JVM, NaCl, PNaCl, flatpak, docker, WebAssembly) if we could just simplify the layers and layers of cruft and abstractions in compiler toolchains, libc implementations, and shared libraries. Practically every laptop and server processor use the exact same amd64 architecture, but we have squandered this opportunity by adding leaky abstractions at so many levels. I can't wait until installing a program on linux is as simple as downloading a static executable and just running it and I hope zig brings this future.
[1] https://www.youtube.com/watch?v=2u2lEJv7Ukw [2] https://www.youtube.com/watch?v=5S2YArCx6vU
Because when there's a security update to (say) OpenSSL, it's better for the maintainers of just that library to push an update, as opposed to forcing every single dependent to rebuild & push a new release.
I am convinced that Drepper's insistence on dynamic linking has set the linux desktop useability and developer friendliness back literal decades.
Other have mentioned the other points: runtime loading (plugins), CoW deduplication and thus less memory and storage.
Dynamic linking was added around Slackware 2.0 timeframe.
For the record: This is pretty close to what AppImage is today. It's not quite 100% because userland fragmentation is so ridiculously bad that it doesn't work out of the box on a few of them, but I personally really wish all Linux software was distributed that way (or static like Zig).
Should every compiler stack have prioritized cross compilation over other features? (I vote: YES). Cross compiling programs has always been a PITA for most languages.
It would be great if Zig cc could be paired with vcpkg [1] for a nice cross-compiling development environment. Looks like vckpg requires a C++ compiler though.
You can't look at C which started in the 1970s and C++ which started in the 1980s and have expected them to even consider cross-compilation, when Autoconf wasn't even released until 1991.
Most other languages make it _possible_ to generate some sort of artifact usable from different operating systems but not necessarily easy. I think Java only relatively recently included a standard way to create a bundle including a minimal JVM distribution with an app to make it usable when the user doesn't have an installed JVM (and again, there were a bunch of different non standard solutions of varying quality before that). Even now I wouldn't say the Java solution is easy to use.
I could continue in this fashion with different languages, but you get the idea.
I heard go is pretty good in ease of cross compilation, and well, looks like Zig is doing great in this area too. Ah! .net core is apparently pretty good in this area these days too.
This is what makes porting hard work. Cross-compiling is only the first step of a long trip.
But it's also fair to say that if we had always considered those things as inseparable parts of the "compiler suite" that might have made everyone better off.
That would be a nice stress test, which would undoubtedly lead to bugs discovered. After enough bugs fixed, the answer would be "yes".
I'll try it!
Otherwise: yeah. It's just clang's main function with a different name slapped on. Linking semantics may differ slightly which could be problematic. But in theory, yes.
Clang can apparently build a vanilla Linux kernel now, no gotchas, actively used by Google for its Linux things (Android, chromeos).
Cross-compiling with clang is complex because it's just a C compiler, and doesn't make assumptions about what headers the target system might use, or what libc it's using, so you have to set all those things up separately.
Zig is (apparently) a new language built on Clang/LLVM, so it can re-use that to provide a C compiler. It also makes cross-compilation easier in two other ways. First, it limits the number of supported targets - only Linux and Windows, and on Linux only glibc and musl, and all supported on a fixed list of the most common architectures. Second, building Zig involves pre-compiling every supported libc for every supported OS and architecture, and bundling them with the downloadable Zig package. That moves a lot of work from the end user to the Zig maintainers.
Like most magic tricks there's no actual magic involved, it's just somebody doing more and harder work than you can believe anyone would reasonably do.
My only gripe is that the syntax and stdlib, although practical and to the point, seem to suffer from some strange choices that somewhat clash with its own, albeit early, "zen" of simplicity.
- '@' prefix for builtin functions, a little strange and macro-looking for my eyes. Why not just plain keywords? And cleanup some of it: `@cos`, `@sin`, also feel like too much when they are already in the stdlib I believe.
- |x| for/while list bind var, why not just for(x in y)? Surrounding pipes are really annoying to type in some foreign keyboards and feel totally needless in 99% of the places.
- inconsistent required parenthesis predicates in block statements in "test STR {}" vs. "if() {}". Either require parenthesis or don't, I don't really care which one.
- prefixed type signatures, `?[]u32` feels a little off / harder to read.
- comment-looking, noisy prefixed multi-line slashes `\\`.
- the need to dig deep into "std" to get your everyday lib functions out "std.io.getStdOut().outStream().print()". `@import("std")` repeated many times.
- consider implementing destructuring syntax early-on to deal with so much struct member depth ie `const { x, y } = p` or `const { math: { add, mul } } = @import("std")`.
- anonymous list syntax with `.{}` is eye catching as the dot implies "struct member" in Zig, but then the dot is everywhere, specially when you do anonymous structs `.{.x=123}`, maybe consider `[1,2,3]` and `[x=123]` given brackets are being used for array length annotation anyways ie `array[]`.
- `.` suffix for lvalue and rvalue pointer deref. Also `"str".` is a byte array unroll if I understood correctly. Here `f.* = Foo{ .float = 12.34 };` looks like it's doing something with `.` to get to the struct members but it's actually just a pointer deref. Also looks like a file or import lib wildcard (`file.*`) to my eyes.
- field access by string clunky `@field(p, "x") = 123;`, with an odd function as lvalue.
Sorry for the criticism, we're seriously checking out Zig for migrating a large C codebase and replacing future C projects. Although we can live with these quirks, they just make the language look a little random and NIH and that worries me and the team. For instance, Golang has great syntax and semantic consistency which is a boost on project steering quality and assured, life-long onboarding for newbees. Please consider widening the spec peer-review process, maybe in a separate Github repo with markdown proposal writeups. Discussing syntax seems superficial given many project and compiler feats under the hood, but it can become sorta "genetic disease" and a deal-breaker for the project on the long run!
This is a pre-release version I know, but it's just that my hopes are really up for Zig as Golang, C++ and Rust never really did it for us as a multi-target sw toochain for various reasons.
for (([100]void)(undefined)) |_, verb| {
And I've been bitten multiple times with line endings having to be \n only.But for supporting more esoteric targets you might be interested in the goals of this ultra-early-stage assembler. ("Planned targets: All of them.")
If you tell me that I can write better, safer code by using Zig, but I can also compile it into a .c artifact that anybody can use, now that is a tempting proposition!
Folks who have achieved great things with llvm (and C++) have done so 'despite' what they used, not 'because of' it.
This has been my conviction for the past 10 years, and I'm glad I never had to touch llvm with a ten foot pole.
I had no doubts it'll soon be surpassed by a common-sense no-bullshit tool-chain.
Has Zig cc achieved that? Great. No? It will or someone (or I) will develop an alternative that will.
I would suggest holding your convictions more loosely.
Out of curiosity: what do you touch with a ten foot pole? I'd be hard-pressed to call GCC or MSVC much better in that regard, and I can think of very few others that are in use anymore.
I mean, I've definitely dreamt about using SBCL or Clozure for things other than Lisp (seeing as they both include their own compilers not dependent on GCC/LLVM), but I've seen effectively zero effort in that direction.
Does yours do loop unrolling, code hoisting, optimise array accesses to pointer increments, common expression elimination etc?
It's a bit unfortunate that (last I checked) there's no "I don't care how it's implemented as long as it's a list" option at the moment (e.g. for libraries that don't necessarily want to be opinionated about which list implementation to use). Should be possible to implement it as a common interface the same way the allocators in Zig's stdlib each implement a common interface (by generating a struct with pointers to the relevant interface functions).
Are there any guides anywhere for calling libc functions from zig? I'm interested in fork/join, chmod, fcntl, and that kind of thing. Do I just import the C headers manually? Or is there some kind of built-in libc binding?
std.os.fork: https://github.com/ziglang/zig/blob/master/lib/std/os.zig#L2... std.os.fcntl: https://github.com/ziglang/zig/blob/master/lib/std/os.zig#L3...
std.os.chmod
std.os.fcntl
Better yet, use the higher level cross platform abstractions. For example instead of fork/join,
std.Thread.create
std.Thread.wait
These will work in Windows as well as POSIX.
Speed? Using Zig should be faster than using Clang directly in many cases. You get the caching system, and I think you can do more complex builds without having to resort to multiple Clang commands from a makefile.
Not sure what you mean with external libraries.
Zig is unable to provide a libc for the chosen target 'wasm32-wasi-musl'
there are plenty of things i feel are serious shortcomings of C (mixing error results with returned values is my big one), but the fact that the set of things the language can do is small and the ways you can do them are limited makes it much easier to write code that is easy to read. and that will always keep me coming back.
If someone could do the same but for a younger generation, I think it'd be very valuable.
Reminded me of the Stanford Builder gg[1], which does highly parallel gcc compilation on aws lambda. make -j2000.
So with a zig cc drop-in, you might get highly-parallel cross-compilation?
Though the two caching systems might be a bit redundant.
musl v1.2.0
mingw-w64 v7.0.0
glibc 2.31"
These are super-important... (Otherwise, someone will be very limited in what they can compile -- the simplest of programs only...).
It's great that you included these, and as source, not as precompiled binaries!
(Also, a well-selected subset is probably the right balance of functionality vs. complexity...)
Anyway, very excited about the future of Zig as a drop-in Clang/gcc replacement!
(Also, having undefined behaviour on unsigned overflow can make some bit twiddling code harder to write. Then again, maybe Zig has a bit-twiddling unsigned-like type without overflow check? Zip allow turning off checks, but then it turns off checks for everything...)
~~Does `zig cc` cross compiler libgcc/compiler-rt on the fly? Does it compile libc on the fly?~~ Nevermind I did not scroll enough, it does compile on the fly. Whew!
As someone who also cares greatly about cross compilation, compilers definitely should step up their game, but `-target x86_64-windows-gnu` elides many details, unless you are confined to a fix set of platforms.
Zig looks like a nice language for kernel development as well: https://github.com/jzck/kernel-zig