Zig 0.4.0 Released
ziglang.org
ziglang.org
When you click "Download & Documentation" there's a link under the headline "master" to the long-form documentation which has some examples: https://ziglang.org/documentation/master/
Edit: also found a blog post with a nice introduction: https://andrewkelley.me/post/intro-to-zig.html and an examples directory: https://github.com/ziglang/zig/tree/master/example
Interesting to see how the language has evolved away from using "%" in the original Hello world:
const std = @import("std");
pub fn main(args: [][]u8) -> %void {
// Print "Hello World!", and believe that no errors will happen
std.io.stdout.printf("Hello World!\n") %% unreachable{};
// Short version:
%%std.io.stdout.printf("Hi!\n");
}
Compared to the newer version : const std = @import("std");
pub fn main() !void {
// If this program is run without stdout attached, exit with an error.
const stdout_file = try std.io.getStdOut();
// If this program encounters pipe failure when printing to stdout, exit
// with an error.
try stdout_file.write("Hello, world!\n");
}Succinct examples on a clean page, no fluff.
I love seeing all the progress with Zig, V, Muon, and Rust. All these languages are potentially-better systems languages than C/C++, with better safety, better definitions, and better semantics. Zig has an explicit goal to be better than C and to replace it.
Right now, the only way to actually see the language in action is to tune in to Jonathan's livestreams on Twitch. He is writing his next game entirely in Jai. He also streams compiler development every now and then (last night was a compiler stream).
Regardless, V lang is another data point that something besides C is a possibility with the modern tools that we have available to us. Whether or not it pans out is almost immaterial. Just the fact that so many people are finding some sort of success or making some sort of progress in this space is enough for me to continue to watch for any new progress in the C competitors.
There's still a lot of work to do, but the language is going to be open-sourced very soon in early June.
Of course I would like to be proven wrong.
You can't because they don't exist. And don't say "release coming in 3 days" or some other BS like you normally do. It seems like a way to divert attention until people forget to check again.
It won't work. I can see 300 dollars a month on your patreon, which is probably why you exaggerate so much.
> Yes, I've done a terrible job with estimations and for 9 months I lived in "release tomorrow" mode.
> Ironically this time it it really is going to be released tomorrow (Feb 7).
I mistakenly assumed based on the title of the original post "About V, the language Volt is written in" that the post was about V, but as you pointed out, based on the parent comment it was actually about Volt.
I think I'm just excited to see your source code for V :-)
Btw you should update the language comparison page, see here https://forum.nim-lang.org/t/4758
C might die, but there's no replacing it. Sorry.
The hard part is build tool compatibility but I think there are a lot of good ideas being worked on actively, Zig and Rust being two examples of advanced programatic control over the build process. With a reasonable linker, it should be possible to combine these and more languages today.
An interesting counter example to the binary interface compatibility story has been Go, which seems to let cgo become less and less functional in each release. The pressure to keep everything in Go is an interesting trade-off. I wonder if certain kinds of systems will be paying for this lock-in later down the line while other languages give much easier ways to gradually evolve and reuse code or adopt libraries from multiple communities removing the need to do yet-another-rewrite in language X kinds of projects. Or perhaps this kind of interoperation is overrated? Time will tell.
That already works, not a hypothetical. I can write, right now, a zig function, call it from rust, slap the whole thing into a library and wrap it with d. It hasn't taken the world by storm because these languages provide support the system c abi and calling convention, but do not embrace it. If I write a fancy templated function in zig, d, or rust, the name mangling, type-information, templating, maybe even call conventions -- are all different. This is why I have been and continue to be disappointed that things like COM or the jvm or cli aren't more popular, because they actually work that way. I can write, right now a clojure function, call it from java and then pass it into kotlin. Effortlessly, it's just an import away. Sure there are, for example, stdlib conflicts in scala but overall it's a much more frictionless experience. The problem? COM is windows-specific, jvm and cli are managed runtimes and people don't like managed runtimes.
Another place I look for a solution is racket, but again it wants to manage too much of the runtime to be practical. What zig is doing with the build system is great, the fact that the build script is actually a fully customizable script means it has a much better chance of taking off, but until I can import a jai module from d and call it in zig, we're gonna have problems.
EDIT: something which possibly almost could have had a good chance of pulling this off is llvm. Except that llvm comes too late in the compilation process to be used to resolve imports and symbols. Something like libclang, maybe, except not specific to c and c++.
Besides there are plenty of OSes written in type safe system languages to learn from, including surviving mainframe OSes.
As for the negativity, Morris worm is now 30 years old and the CVE database gets C derived exploits every month.
(That doesn't make Object Pascal a practical language, though).
https://www.quora.com/Why-is-the-JVM-so-riddled-with-securit...
Another fact is, startup times alone make JVM impractical for many endeavours. For each task an appropriate tool I'll say.
Good news, now OpenJDK and GraalVM offer it for free, gratis.
Object Pascal/Delphi is quite pratical on Windows.
It has a sane subset which is basically C with a slightly saner syntax than C (the begin...end and lacking data initialization syntax are terrible though!), and with a proper module system and much better compile times.
On the other hand, it was crippled by missing a usable preprocessor and an ecosystem that has bought into each hype since the 90's, resulting in 23 incompatible kinds of strings, 101 different dynamic arrays, and about 5 (really) incompatible object models with different kinds of memory management. Programmers with many years in the language don't really understand all the ways memory is managed in this language.
Now try writing something on top of the broken RTTI for that. Even official guides basically concede the fact by writing quirky code that easily breaks.
Also you have to declare typealiases for every little thing like pointer-to-types, before you can use that type in a function signature. This alone renders it almost completely unusable for my purposes.
It has a culture of goto-considered-harmful where people like to indent 13 times instead of using return/continue/break, which would yield readable control flow. If you want to return something, you need to write two lines - assigning to the result and calling exit(). You can't call exit() though when the current class has a method called exit(), since that method is closer in scope (REALLY REALLY WEIRD).
I know what I'm talking about. I've been paid to work in it, and refactored a subsystem written in idiomatic Delphi to be halfway maintainable, achieving real speedups of 100-1000x by following a straightforward "data-oriented" approach, just like I would write it in C, writing complicated code only where the straightforward approach was not feasible in the language. Despite completing the project successfully (there hasn't been a single problem since the rewrite), in the end I was burnt out due to having to work with the original code. Didn't work for 5 months afterwards.
Except for when I write Assembly, the last time I used raw goto on an high level language, my MS-DOS 5.0 box was still relatively new.
System.exit was always a thing to avoid namespace clashes and since Delphi 2009, you could have used System.exit(value) instead. Next time better read the docs.
Regarding strings, you mean like 8 bit, 16 bit, wchar_t, DBCS, GString and many others used across C libraries?
Nominal typing is much safer for large scale engineering than type aliases, which don't provide a mechanism to prevent incorrect usage of types.
Do you suggest I should use System.exit everywhere (even though all the code you find on the net uses just "exit")? Just to be sure that Delphi will never ever choose the wrong function to call WHICH IT SHOULD NEVER HAVE DONE IN THE FIRST PLACE OMG IT'S TOO FRIGGING COMPLICATED PLEASE DELPHI APPLY SOME COMMON SENSE.
It's beyond me why I should write a function call and incur symbol resolution for such basic control flow in the first place.
> the last time I used raw goto
I was mainly speaking about return, break, continue, which don't seem to be popular in Delphi. Examples of Delphi code that isn't a messy nesting fest? As for goto, there are perfectly valid uses for it, in fact some where goto is the clearest and most maintainable choice when you simply skip downwards over a chunk of code without requiring an extra flag.
> Regarding strings
I'm talking about the culture. The culture around C is not one that makes anti-modular "abstractions" (at least if you stay away from MS). You will never see me using wchar_t, GString or any of that god-awful Microsoft string mess. I get along just fine with only char. In fact, the string handling I get by using C is the most painless, most modular I've ever gotten in any language. (No, I don't want to use split() or use any other high-level stuff that would do allocations when that isn't necessary).
In Delphi, different story. Everything you find in this culture is built around String and AnsiString and UnicodeString and WideString and what not. Try googling how to access command-line parameters. The stuff is pervasive. Entirely different story.
> Nominal typing is much safer for large scale engineering than type aliases, which don't provide a mechanism to prevent incorrect usage of types.
Exactly, typealiases are bad. And now explain to me why Delphi forces me to make a type alias (for use in function signatures) when that is worse than immediate Pointer syntax in every conceivable aspect? (Having written a compiler I know the answer: because it requires less code in the compiler to check for type equality).
So I guess I should just avoid pointers altogether and use only GC'ed boxed OOP NOMINAL types. And finally have some time for coffee again while my application takes 5-10 minutes to start up (as it did before I reworked the thing), instead of 1 sec.
end;
end;
end;
end;
end;
end;
end;As for type safe system languages, ada?
It's from the team who delivered cppwinrt (aka moderncpp). So the C++ projection doesn't have all the nasty baggage one usually associates with COM. https://msdn.microsoft.com/en-us/magazine/mt745094.aspx?f=25...
Same applies on Android, where using a Java based library, even if stuck on their Java 6 - 8 world is much more desireable than having to deal with NDK and JNI boilerplate.
Likewise IBM and Unisys mainframes make use of their language environments instead of C based ABIs.
Assuming with COM/UWP you mean "UWP's flavor of COM" instead of "COM and/or UWP", is anyone actually using that outside of mobile trash and game engine backends for XB1?
All the Windows software i use and see people make are either Win32 or (much more often) built on top of Win32 (well, UWP is technically also built on top of Win32, but you are supposed to ignore that and act as if it isn't the case).
Win32 is slowly being migrated into sandbox model with each Windows 10 release and hasn't seen any big update since Vista. All major APIs introduced since then are based on COM.
The year of desktop Linux is just around the corner. /s
It doesn't look like Microsoft has lost faith in UWP, only that they gained faith in UWP/Win32 hybrids (and all the complicated engineering work to make that happen), and Office seems to have helped lead the way there. For instance, Office is way more sandboxed than it has ever been before. (Office's own App-V work as far back as Office 2010 helped prototype the sandboxing approach Microsoft is applying to all of Win32 with the now focused opt-in MSIX installer.)
It's probably still too early to tell exactly how much UWP Microsoft will add to their Chromium mix, but there's already some bits there. For instance, the Chromium-based Edge still supports Netflix because they already integrated a UWP Island to (UWP API) Windows Media Foundation to support hardware-accelerated PlayReady DRM.
Well, i don't, but my two main gripes is that it seems to be an evolution of WPF which i never liked and that it is tied to a more locked down mobile-like approach that i abhor.
> Win32 is slowly being migrated into sandbox model with each Windows 10 release
What are you talking about?
> and hasn't seen any big update since Vista.
I'd say that it hasn't seen any big update since Windows 98 :-P but as long as it works i do not care.
> All major APIs introduced since then are based on COM.
COM or COM/UWP?
Based on COM, and UWP, which is nothing more than a saner COM, now being internally widespread via C++/WinRT adoption.
Zig and Jai aren't going anywhere. Zig appears to be a largely single contibutor (https://github.com/ziglang/zig/graphs/contributors the creator has < 2/3 of commits). Jai does not have a public compiler and is not likely to get a public release anytime soon.
As for rust we don't know yet how big of a chunk of marketshare it will take from new c and c++ code.
Not many people still use c code for "everything", most have already switched.
There are 8 people on the Zig team, all with significant contributions and deep understanding of the project. https://github.com/orgs/ziglang/people
That's a good thing. The less contributors, the better the project usually.
Aside from starting Zig as his personal project, Zig is also Andrew's job now. As far as I'm aware that is not true of any other contributor, so it makes sense he'd have the lion's share of contributions.
No they are not. C++ has spent decades building "a better C/C++". Any language that ignores those lessons and takes the stance of "learning C++ is too hard, let's go shopping" is doomed to fail.
<rant> For all the time and work poured into C++, it has remarkably little to show over plain old C99.
Some of those new "better C" languages are the work of individuals and very small teams, yet they are able to build more progressive "better C" languages than C++ can ever be because it is held back by the need for backward compatibility for 'failed features' and 'design-by-committee'.
If all that ever comes out of those small 'better C' languages is some sort of consensus of which core-set of features actually makes a 'better C', than they have already contributed more to programming language development than C++. </rant>
- RAII
- exceptions
- classes and objects
- inheritance
- templates
- the STL
C++ is strictly better than C when wielded correctly.
- RAII: Only useful with 'smart' data which must run code for initialization, destruction or copying. It's entirely valid to work with 'dumb' data only which is zero-initialized, and can be copied and deleted without any additional custom actions.
- Exceptions: too brittle and complex, modern languages have switched mostly to option-return values, which contain both an error code and success-result.
- Classes, objects, inheritance: left-over artefacts from the OOP hype of the 90's
- Templates: Not the only option to write generic code, other languages do this better. Programming entirely without generics isn't too bad either, not all code benefits from this.
- STL: not sure what to say here, it's the main contributor to slow compile times, excessive hidden memory allocation, slow debug performance and bloated executables. There are not many parts of the STL that are 'acceptable', but of course that's entirely subjective.
Better than template without uniform representation? template is just copy-paste you don't _have_ to use it. Same remark for STL. You want a hashmap of arrays of string, you can have it in C++ in one line. In C you would end up with a linked list instead of picking the right data structure.
Objects and inheritance are not a hype. See this page, which uses CSS, which implements inheritance. Having subtyping is a basic premise of being a useful language (or, a GUI language).
Alternatively, you'll learn to not appreciate the value of exceptions working on high-availability software. Not personal experience, but AFAIK Google (definitely lots of highly-available software) disallows using exceptions in C++.
> Because most existing C++ code at Google is not prepared to deal with exceptions, it is comparatively difficult to adopt new code that generates exceptions[....] Things would probably be different if we had to do it all over again from scratch. - https://google.github.io/styleguide/cppguide.html#Exceptions
They're not. People vastly more experienced and more intelligent than you came up with them. Learn why they exist before dismissing them.
You won't get anywhere trying to replace C with a "let's go shopping instead" mentality.
Exactly. I think of it as a path-finding problem. C was obviously not where people wanted to be. As with any path-finding problem, it's possible to make a wrong turn. Often, attempts to recover without backtracking only make things worse. I contend that C++ has done exactly this. They're at point where a mature, reasonable person would admit their error and backtrack until a better path can be found.
I doubt that many of C++'s critics are arguing from ignorance or afraid of complexity. More often, they're objecting to spurious complexity because they know how to do better. I've written compilers, and they're not even close to being the most complex things I've written. It's not so much "let's go shopping" as "let's return this defective merchandise" and build something that works. It's only the lemmings who insist on rushing further down the wrong path. "Turning around is hard; maybe if I get enough others to come with me they'll break my fall."
If there's one truth I've learned in my decades of dealing with computers, it's that you can't beat C at being C.
Before now, I'd never heard of Zig in particular, but I can think of several other languages that have tried or are currently trying. A lot of people seem to think they can make something a little better than C, in some ways, and that will be enough. I doubt that even C18 itself, if it were invented from scratch today, would be able to unseat another systems programming language.
Everybody forgot about Worse-is-Better: "Unix and C are the ultimate computer viruses". Any language which isn't more 'viral' than C (in terms of being ported, and attracting users) has no chance. You're starting tiny, and growing less quickly.
Have you ever seen a language that has made a serious attempt?
The last few years, the only significant one I know of is Rust. But it's not really a C replacement. C is essentially fancy assembly. Rust is conceptually quite advanced.
Zig is one of very few languages I've seen that makes a serious attempt at being a better C. No garbage collection, no fancy borrowing checker, but quite a few improvements/features that actually matter to low-level/embedded programming.
My use-case is microcontrollers, and I've tried a few different new languages for fun. Zig is the first one where I actually came out of it wanting to use it for real. The only problem is it's still not finished.
Their sin was not being bundled with an OS, originally distributed with source code by a symbolic price.
As for Oberon, Astrobe is still in business.
I don't really want to restart a flame war that was extinguished decades ago but Kernighan's critique of Pascal (http://www.lysator.liu.se/c/bwk-on-pascal.html) is an interesting read today - if only because it reminds me how much simpler things were back then - no mention of memory safety or multi-threading.
I have no knowledge of Object Pascal and Modula-2, so won't comment.
Cleverly not mentioning that many issues were fixed on ISO Extended Pascal and other dialects.
Also that back then outside Bell Labs, most C compilers were actually dialects of the real thing, like Small C and RatC. So it was not like C wasn't without its portability issues outside UNIX.
As for memory safety and multi-threading, check Concurrent Pascal and Solo OS from Per Brinch Hansen.
Yes, Kernighan was “clever” in 1981 to ignore ISO Extended Pascal, a standard published in 1991. (I'm also not sure if there was ever more than one implementation of Extended Pascal, though Free Pascal claims it as a planned future feature.)
Many of them available in 1981 dialects
Was not abandoned, it was rebranded to “Delphi” and is still around.
It's not obvious what needs to come next, which is the only reason that C is still here. Most likely several languages are needed to fully replace it. And our industry is starting to feel that out now.
D, Go, Rust, Jai, Zig, P, C# low level primitives. Things are changing. Even C++ seems to want to be a different language with some of it's latest developments.
I think it's fine to have aspirational but unrealistic goals.
> If there's one truth I've learned in my decades of dealing with computers, it's that you can't beat C at being C.
You can't, but as the realm of computing expands, it makes space for new languages. There's a lot of room in the space adjacent to C. We have embeddable languages -- schemes, lua, even Python to some extent. We have languages like Zig, Rust, and D, that can compile to object files that look as if they came from C. And we have other languages that generate C, like lisps and ocaml have done for 20 years now.
C doesn't have to be a language anybody writes, to be a language that everybody uses.
Some of my personal highlights:
- clean syntax
- comptime (as explicit and simple as it should be)
- reflection
- minimal/no external dependencies
- single threaded mode (instead of taking cuts at runtime)
- concise and explicit error handling
- build-in build system
- amazing C interop
...
Good sample code can also be found in the standard library, and it has the benefit of being up to date with with language.
Thanks Andy!
- "zig is also a C compiler" . Flag-compatible with clang, and with integration with zig's buildsystem you get cached build artifacts.
- Cross compile for a boatload of architectures + musl or glibc - in a ~30Mb compressed package
Another small annoyance was Zig rejecting \r in line endings. Thankfully, I'm using Emacs so it only took me 15 minutes to google the right fix. But it felt a little "gratuitous" if you know what I mean.
The code itself should be up to date for most, but I'm aware of a few examples than need touch-ups. Unfortunately there is a bit more boilerplate compared to other languages for some simple tasks, since Zig requires you to be quite explicit about things (e.g. i/o, memory allocation).
Regarding the rejection of '\r', there is the intention for `zig fmt` to handle these minor issues and reformat code as needed which hopefully reduces this barrier. There was a long issue regarding hard tabs with discussion here: https://github.com/ziglang/zig/issues/544
It's been a real pleasure seeing Zig grow, hopefully it can fill that niche for a high performance, portable, modern language that isn't filled with OOP cruft
https://ziglang.org/download/0.4.0/release-notes.html#Build-...
I've been playing around with embedding sqlite for a Rust project and checking the C into the source tree made sense there too.
Zig claims very proudly it is about clarity but shortly into reading through the documentation I already found this extremely surprising:
"Multiline string literals have no escapes and can span across multiple lines. To start a multiline string literal, use the \\ token. Just like a comment, the string literal goes until the end of the line."
I could not have tried to make a more confusing token for multiline string literals if I tried. The difference between a string literal and comments is literally whether or not the lines are preceded by an open =.
Well comments use forward slash (//) and string literals use backslash (\\)
Python has an even closer relationship between comments and string literals: its multiline comments are just string literals that get never used.
That's not entirely true. A literal string immediately following a class or function is inspectable via its __doc__ member.
E.g. class Foo: "I am Foo." def bar(self): "I am Foo.bar"
Foo.__doc__ will have "I am Foo.", and Foo.bar.__doc__ will have "I am Foo.bar".
This is rarely used programattically, but at least one standard module uses this for running tests: doctest
Edit: not sure why it's not formatting correctly, as I am spacing the code a 4 space indent, but at least on my phone, it is not properly formatting as code. I apologize.
Either pythons stdlib crappy pydoc module
`python -m pydoc -w ModuleName`
the simple pdoc tool
`/path/to/pdoc --html ModuleName`
or the complicated and fully featured sphinx (too complicated for a single command
`sphinx-apidoc ModuleName` to generate a default project
and `make`/`make.bat` to run it )
They are also useful print help in repl (with `help(obj)` or `obj?` in IPython)
Also in python comments are everything after a hash # till end of line.
Non assigned Literal strings in python are just literal objects not comments.
If they are the first thing in a class/function they become the class/function/method __doc__ attribute.
If they aren't they have no use but are simply created and then garbage collected because there are no references pointing to them(cpython the default python implementation uses reference counting and the occasional cleanup of unreachable cycles so it would be deleted right after creation). Its the same with literal numbers or dictionaries.
def a():
5
[]
"whoop de do"
is a legal (and totally pointless) python function that will do nothing(other then allocate then cleanup some objects).Why this algo in particular? Is this a security feature? I suppose wrt "Reflections On Trusting Trust" it may be. But if it didn't need to be secure it could probably be a lot faster (assuming this is a critical path for cache hits).
I haven't tested the performance of any other algorithms, but that's a completely swappable component. I'm sure the hash function will be swapped with a different one before 1.0.0 is done.
It would be more fair to not even mention them as supported _at all_, or at the very least to document them as Tier 4.
I haven't played with Zig but it looks a lot more appealing than e.g. Rust to me.
In the end though, I'll prefer plain old C (C99 or C11).
const std = @import("std");
* pointless semicolon* pointless "@"
* seemingly pointless "const" (can you define a mutable import?)
* unnecessary verbosity defining an identifier for the import when there's almost never a need for naming it differently (i.e. it should default to "const std" if you just type "import 'std'"...
I like Go because it avoids pointless verbosity most of the time.
There might be very good reasons for each of those things, but it's hard to say without delving into it some more.
Except for all those times you had to manually write err != nil
but then you've just imported all of std into your own namespace. (probably not using the correct terminology here).
At any rate the const indicates you're not changing, and the std is the name given to the root of the hierarchy for importing "std" into.
Sure go lets you do this too, but has shorthand.
import "fmt"
can also be done as import fmt "fmt"
but why would you do that?The go equivalent of zig's "use" is
import . "fmt"
"." means "the current working directory" on unix so it's familiar to folks in that sense perhaps. Principle of least surprise is nice when the syntax is terse.Still, I think I like zig. I feel like I want to try to write something non-trivial with it when I look at the features.
I've already done that a few times with Go, and I enjoy that too.
It's noticeable that there are a lot of differences, and some things seem to have been deliberately made different (even if they are in essence very similar and only syntactically different), so for me it looks a bit odd that most references to Rust on his blog nowadays are of adversarial nature (ie, "look how better we are than Rust").
Last, but not least, it also doesn't help with the big picture that the one continuously posting links about Zig here is just self-promoting their own creation...
Anyway, just my $0.02
> the one continuously posting links about Zig here is just self-promoting their own creation
Nothing wrong with that. If their creation fails to excite people, there won't be any conversation, it won't make it to the first page, etc.