Hacker News new | ask | show | jobs
by samatman 767 days ago
Let's say you have a C program to write, and you really want exhaustive pattern matching on the tags of unions (which is what Datatype99 provides: "Put simply, Datatype99 is just a syntax sugar over tagged unions").

Let's say further that you already know Rust exists, and aren't going to use it for reasons that anyone writing a C program already knows.

At least consider Zig. Here's a little something I wrote in Zig two days ago:

    /// Adjust a label-bearing OpCode by `l`. No-op if no label.
    pub fn adjust(self: *OpCode, l: i16) void {
        switch (self.*) {
            inline else => |*op| {
                const PayType = @TypeOf(op.*);
                if (PayType != void and @hasField(PayType, "l")) {
                    op.*.l += l;
                }
            },
        }
    }
This uses comptime (inline else) to generate all branches of a switch statement over a tagged union, and add an offset to members of that union which have an "l" field. You can vary the nature of the branches on any comptime-available type info, which is a lot, and all the conditions are compile-time, each branch of the switch has only the logic needed to handle that variant.

"But my program is already in C, I just need it for one file" right. Try Zig. You might like it.

2 comments

> At least consider Zig.

Considered the example given. Now my eyes hurt. I think I started appreciating Lisp more.

Seems like Nim can be useful too, plus it compiles to C.

https://gist.github.com/unclechu/eb37cc81e80afbbb5e74990b62e...

I've been a Nim respecter for many years, it's slept on in general as a language.

The difference here is that Nim compiles to C and you can turn the garbage collector off: Zig compiles C and there's no garbage collector. That means the entire standard library is available when generating object code. It's also trivial to opt-in to the C ABI on a fine-grained basis, by defining a function or struct with the extern keyword.

I believe this is still fairly current about the difficulties of building Nim dylibs for C programs: https://peterme.net/dynamic-libraries-in-nim.html

I expect Nim will stabilize about where D has: it will have a dialect of the language which, with relatively painless accommodations, is able to produce object code which speaks C ABI. Zig is different. The language is relentlessly focused on providing a better alternative to C while occupying the same niche, and a lot of design time has been spent on making it practical to take an existing C program and start writing the new parts of it in Zig.

It's a good language, Nim, and getting better. I'd recommend it for someone who is considering Go, for example.

I think this is all true. Though with regard to your earlier example, it should be noted that Nim, too, has an extraordinarily powerful compile-time programming system: but it takes the form of typed macros and generics (as opposed to Zig's dislike for such abstractions).
Let's say further that you already know Zig exists, and aren't going to use it for reasons that anyone writing a C/Rust/D/C++ program already knows.

At least give Nim a try.

The difference here is that there aren't C programmers who don't know about Rust, and since they're writing C, they have reasons they aren't using it. The same is not true of Zig. Some of the reasons not to be using Rust may be applicable (no specification comes to mind), others may not be.

I do agree that, on an even playing field, Nim should be considered when any of Rust, D, C++, or Go, are on the table. This is less true of C, and therefore, Zig. There's a difference between something being possible, and something being easy and pleasant.

There are also people using C, who really should be using some other language. Which is, in that case, probably not Zig. When you understand that C is the rational choice for some sorts of programming, you'll understand why Zig is a contender, in a way that the other languages we're discussing are not.

Maybe I’ll understand one day.
In Nim, ADTs are painful still (as your example clearly shows), but they are working on adding proper ADTs to the language (I can't find where I read that, but I am sure I did!).