Generics in Zig and Rust

(730 words)

I was talking the other day about creating a SparseArray data type in Zig, using a function that takes two types and returns a type. This is elegantly simple to view and understand. I said at the end of that post that new languages like Zig don’t have to follow the legacy approach that C++ does with < and > templates. I was going to include Rust in that set of modern languages until I remembered that Rust does the whole <> thing.

more...

Sparse Arrays and type composition in Zig

(1504 words)

One of the lovely things about Zig is the way that you can just create types at compile time and then use these types elsewhere in your code. The other day, I needed a sparse array, but the standard library didn’t really have what I wanted. I could have used one of the hash-map types, but that wasn’t really what I wanted, so I created my own.

pub fn SparseArray(IndexType: type, DataType: type) type {
}

The first thing I did was create a function that returns a type and takes in the types that I’d be using for the index and data types.

more...

Calculating primes

(1381 words)

Creating a list of primes takes a long time. This is especially true if you are using the very boring and simple sieve algorithm. In Zig, this is really easy to do:

pub fn calculate_prime_numbers (comptime size: usize) std.StaticBitSet(size) {
    var sieve = std.StaticBitSet(size).initFull();
    sieve.setValue (0, false);
    sieve.setValue (1, false);

    const last: usize = @intFromFloat(@sqrt(@as(f64, @floatFromInt(size))));

    for (2..size) |n| {
        if (sieve.isSet(n)) {
            results.set(n);
        }
        var i: usize = n * 2;
        while (i <= last) : (i += n) {
            sieve.setValue(i, false);
        }
    }
    return results;
}

The code is really simple. It creates a sieve set, initially full, except for the number 0 and 1. It then looks through from the number 2 up to the square root of the size parameter given, and then looks at the sieve set to see if the bit is set. If it is, then it goes from double the current number up to the size parameter jumping by the current number, and clears the sieve bits, effectively removing all the multiples of the current number as not prime for future iterations.

more...