I totally vibe with the intro but then the rest of the article goes on to be a showcase bits of zig.
I feel what is missing is how each feature is so cool compared to other languages.
As a language nerd zig syntax is just so cool. It doesn’t feel the need to adhere to any conventions and seems to solve the problems in the most direct and simple way.
An example of this declaring a label and referring to a label. By moving the colon to either end it makes labels instantly understood which form it is.
And then there is the runtime promises such as no hidden control flow. There are no magical @decorators or destructors. Instead we have explicit control flow like defer.
Finally there is comptime. No need to learn another macro syntax. It’s just more zig during compilation
I was also curious what direction the article was going to take. The showcase is cool, and the features you mentioned are cool. But for me, Zig is cool is because all the pieces simply fit together with essentially no redundancy or overloading. You learn the constructs and they just compose as you expect. There's one feature I'd personally like added, but there's nothing actually _missing_. Coding in it quickly felt like using a tool I'd used for years, and that's special.
Zig's big feature imo is just the relative absence of warts in the core language. I really don't know how to communicate that in an article. You kind of just have to build something in it.
> Coding in it quickly felt like using a tool I'd used for years, and that's special.
That's been my exact experience too. I was surprised how fast I felt confident in writing zig code. I only started using it a month ago, and already I've made it to 5000 lines in a custom tcl interpreter. It just gets out of the way of me expressing the code I want to write, which is an incredible feeling. Want to focus on fitting data structures on L1 cache? Go ahead. Want to automatically generate lookup tables from an enum? 20 lines of understandable comptime. Want to use tagged pointers? Using "align(128)" ensures your pointers are aligned so you can pack enough bits in.
Having spend a year tinkering in zig and it's absence of features has made me want to drop c#/java professionally and pick up Golang. Its quiet annoying when you see a codebases written in C#/java and you can tell in which year/era it was written because of the language features. The way of writing things in C# changes like every 4 years or so.
There's a certain beauty in only having to know 1~2 loops/iteration concepts compared to 4~5 in modern multi paradigm languages(various forms of loops, multiple shapes of LINQ, the functional stuff etc).
Something akin to interfaces, but weaker. Right now people roll their own vtables or similar, and that's fine...I actually don't expect these to be added. But because of Zig's commitment to "everything structural is a struct", a very very simple interface type would likely end up being used more like ML's modules.
The need for this jumped out at me during Writergate. People had alot of trouble understanding exactly how all the pieces fit together, and there was no good place to document that. The documentation (or the code people went to to understand it) was always on an implementation. Having an interface would have given Zig a place to hang the Reader/Writer documentation and allowed a quick way for people to understand the expectations it places on implementations without further complications.
For Zig, I don't even want it to automatically handle the vtable like other languages...I'm comfortable with the way people implement different kinds of dynamic dispatch now. All I want is a type-level construct that describes what fields/functions a struct has and nothing else. No effect on runtime data or automatic upcasting or anything. Just a way to say "if this looks like this, it can be considered this type."
I expect the argument is that it's unnecessary. Technically, it is. But Zig's biggest weakness compared to other languages is that all the abstractions have to be in the programmer's head rather than encoded in the program. This greatly hampers people's ability to jump into a new codebase and help themselves. IMO this is all that's needed to remedy that without complicating everything.
You can see how much organizational power this has by looking at the docs for Go's standard library. Ignore how Go's runtime does all the work for you...think more about how it helps make the _intent_ behind the code clear.
The feature I want is multimethods -- function overloading based on the runtime (not compile time) type of all the arguments.
Programming with it is magical, and its a huge drag to go back to languages without it. Just so much better than common OOP that depends only on the type of one special argument (self, this etc).
Common Lisp has had it forever, and Dylan transferred that to a language with more conventional syntax -- but is very near to dead now, certainly hasn't snowballed.
On the other hand Julia does it very well and seems to be gaining a lot of traction as a very high performance but very expressive and safe language.
I think this is a major mistake for Zig's target adoption market - low level programmers trying to use a better C.
Julia is phenomenally great for solo/small projects, but as soon as you have complex dependencies that _you_ can't update - all the overloading makes it an absolute nightmare to debug.
For what it's worth, that hasn't been my experience with Julia – I've found it easier to debug than Python, Scala, or Clojure (other languages I've used at jobs.)
The tooling makes it easy to tell which version of a method you're using, though that's rarely an issue in practice. And the fact that methods are open to extension makes it really easy to fix occasional upstream bugs where the equivalent has to wait for a library maintainer in Python.
500kloc Julia over 4 years, so not a huge codebase, but not trivial either.
>The feature I want is multimethods -- function overloading based on the runtime (not compile time) type of all the arguments.
>Programming with it is magical, and its a huge drag to go back to languages without it. Just so much better than common OOP that depends only on the type of one special argument (self, this etc).
Can you give one or two examples? And why is programming with it magical?
For a start it means you can much more naturally define arithmetic operators for a variety of built in and user-defined types, and this can all be done with libraries not the core language.
Because methods aren't "inside" objects, but just look like functions taking (references to) structs, you can add your own methods to someone else's types.
It's really hard to give a concise example that doesn't look artificial, because it's really a feature for large code bases.
I feel what is missing is how each feature is so cool compared to other languages.
As a language nerd zig syntax is just so cool. It doesn’t feel the need to adhere to any conventions and seems to solve the problems in the most direct and simple way.
An example of this declaring a label and referring to a label. By moving the colon to either end it makes labels instantly understood which form it is.
And then there is the runtime promises such as no hidden control flow. There are no magical @decorators or destructors. Instead we have explicit control flow like defer.
Finally there is comptime. No need to learn another macro syntax. It’s just more zig during compilation