I recently started diving into Zig, a systems programming language. What initially drew me in was its resemblance to C, its robust build system, and its modern features. At work, I primarily deal with high-level languages like JavaScript, TypeScript, and Java, so Zig offered a refreshing change of pace.

I’ve always aspired to contribute to open-source projects. The allure lies in the inherent challenge, the opportunity to interact with other developers beyond my immediate colleagues (no offense to them!), the chance to lend a helping hand, and the invaluable learning experience. However, I consistently struggled to find a suitable project – a library, a framework, or a tool – that sparked my interest. In retrospect, I might have been subconsciously procrastinating. It can be daunting to take that first step when you’re an outsider with no prior open-source experience.

Then, serendipity struck. While writing an article for our company’s internal blog, I needed to include a screenshot of some code to illustrate a point. To achieve this, I decided to write a small, albeit purposeless, program in Zig, incorporating a library in the process.

The Challenge

My program was designed to be a simple command-line interface (CLI) that could read arguments and output text. To handle argument parsing, I sought a suitable library. I was familiar with clap, a popular Rust library, and discovered its Zig counterpart: zig-clap.

I integrated zig-clap into my project and defined a few dummy arguments. When defining an “age” argument, I opted to use an unsigned integer type (usize).

Upon testing my revolutionary tool, I entered an age, and it correctly outputted “Age: 24.” However, my curiosity got the better of me. What error message would appear if I inputted a negative number? Zig enforces rigorous error handling, so I anticipated an error message indicating that negative numbers are invalid for unsigned integers.

To my surprise, the program displayed ParseIntError.InvalidCharacter. This was an unexpected and somewhat cryptic error message for this scenario. It appeared that the library was attempting to parse unsigned integers as signed integers, interpreting the leading minus sign as an invalid character.

The Fix

This unexpected behavior ignited my curiosity and provided a clear purpose: to rectify this error. For the sake of humanity (or perhaps simply for the fun of it), I embarked on my open-source journey.

I began by forking and cloning the zig-clap repository. The Zig CLI streamlined the process, seamlessly handling the compilation and ensuring I had the necessary compiler and libraries installed with a simple zig build command.

I quickly located the code responsible for parsing uint values, and the error was glaringly obvious:

.u8 = int(u8, 0),
.u16 = int(u16, 0),
.u32 = int(u32, 0),
.u64 = int(u64, 0),
.usize = int(usize, 0),
pub fn int(comptime T: type, comptime base: u8) fn ([]const u8) std.fmt.ParseIntError!T {
    return struct {
        fn parse(in: []const u8) std.fmt.ParseIntError!T {
            return std.fmt.parseInt(T, in, base);
        }
    }.parse;
}

As I suspected, the code was incorrectly calling parseInt on unsigned integers.

The fix was straightforward: I simply needed to replace the calls to parseInt with calls to parseUnsigned for the unsigned integer types.

The Merge

I then created a pull request, providing a clear explanation of the issue and my proposed solution. Within a few hours, the project maintainer provided valuable feedback, suggesting a more elegant solution using Zig’s comptime feature to conditionally call the appropriate parsing function based on the type’s properties.

I implemented these suggestions, pushed the updated code, and eagerly awaited the outcome. The next day, I was thrilled to see that my changes had been successfully merged into the main branch.

Moving Forward

Although a relatively minor contribution, this experience instilled a sense of pride and accomplishment. Knowing that my code would now be used by others was incredibly rewarding.

I am eager to continue seeking opportunities to contribute to open-source projects, whether it’s further enhancing zig-clap or exploring other projects that pique my interest. Perhaps one day, I’ll find a main project where I can dedicate a significant portion of my time.

I strongly encourage others to embark on their own open-source journeys. It’s an immensely rewarding experience. In a few years, when I have accumulated more open-source contributions, I plan to write another article reflecting on my journey with deeper insights.