There comes a time in any software program developer’s life once they have a look at their achievements, the traces of code written and the programming languages they’ve relied on, earlier than questioning whether or not there could also be extra on the market. A programming language and its related toolchains start to really feel like acquainted, well-used instruments after you employ them for years, however that’s no excuse to stay rusted in place.
Whereas some builders wish to zigzag from one language and toolset to a different, others are extra conservative. My very own journey took me from a childhood with QuickBasic and VisualBasic to C++ with a little bit of Java, PHP, JavaScript, D and others alongside the way in which. Though I’ve now for years centered on C++, I’m presently getting the grasp of Ada specifically, each of which tickle my internal developer in numerous methods.
Though Java and D by no means fairly reached their lofty guarantees, there are all the time new languages to research, with each Rust and Zig specifically getting a variety of consideration as of late. May they be the salvation that was promised to us C-afflicted builders, and do they make you wish to zigzag or ferrously oxidize?
Fixing Issues
As hilarious it’s to make new programming languages for the enjoyable of it, there must be some function to them in the event that they wish to be greater than a gag. That’s why Whitespace and Brainf*ck are nice for having some (instructional) enjoyable with, whereas Forth is a severe and really a lot commercially profitable language. In the meantime there’s nonetheless an ongoing debate about whether or not Python might or might not be an esoteric language, totally on account of it granting whitespace a lot relevance that will make the Whitespace builders proud.
This contrasts closely with languages like C and consequently C++ the place whitespace just isn’t related and you may write every thing on a single line if that’s your kink. In the meantime in Ada, COBOL and others case sensitivity doesn’t exist, as a result of their builders did not see the purpose of including this ‘function’. This leads us to a different distinguishing function of languages: weakly- versus strongly-typed and super-strongly typed languages.
If one accepts {that a} kind system is there to forestall errors, then logically the stronger the kind system is, the higher. That is one motive why I personally want TypeScript over JavaScript, why Java reflection and Goal-C messaging drove me up varied partitions, why my favourite scripting language is AngelScript, why I like the kind system in Ada and likewise why I detest whoever accepted utilizing the auto key phrase in C++ outdoors of templates.
With these traces marked, let’s see what issues Rust and Zig will clear up for me.
Getting Ziggy
The Zig language is fairly new, having solely been launched in early 2016. This makes it 4 years youthful than Rust, whereas additionally claiming to be a ‘higher C’. A lot of that is supposed to return from ‘improved reminiscence security’, which is a subject that I’ve addressed beforehand, each within the context of one other ‘improved C’ language referred to as TrapC, in addition to from a safety pink herring perspective. Right here once more having a really robust kind system is essential, as this permits for the compiler in addition to static and dynamic evaluation instruments to choose up any points.
There may be additionally the wrinkle that C++ is already an improved C, and the C11 commonplace specifically addresses a variety of undefined habits, which makes it a reasonably tall order to do higher than both. Thankfully Zig claims to be a virtually drop-in answer for present C and C++ code, so it must be fairly light to get began with.
Sadly, that is the half the place issues quickly fell aside for me. I had the thought to rapidly put collectively a crude port of my ncurses-based UE1 emulator challenge, however the first shock got here after putting in the toolchain. My default growth setting on Home windows is the Linux-like MSYS2 setting, with the Zig toolchain accessible through pacman.
A sense of dread started to set in whereas glancing on the Getting Began web page, however I figured that I’d throw collectively a fast ncurses challenge based mostly on some two-year previous code that somebody mentioned had labored for them:
const std = @import("std");
const c = @cImport({
@cInclude("curses.h");
});
pub fn predominant() !void {
var e = c.initscr();
e = c.printw("Good day World !!!");
e = c.refresh();
e = c.getch();
e = c.endwin();
}
Regardless of the image soup and continual worry of absolutely writing out English phrases, it’s not too onerous to grasp what this code is meant to do. The @cImport() block means that you can embrace C headers, which on this case permits us to import the usual ncurses header, requiring us to solely hyperlink in opposition to the system ncurses library in a while. What’s not inspiring a lot confidence is that it’s clear at this level already that Zig is a weakly-typed language, bringing again extremely undesirable embedded JavaScript flashbacks.
Whereas prodding at writing a regular Makefile to compile this code, the truth of the Zig construct system started to hit. You possibly can solely use the zig command, which requires a particular construct file written in Zig, so it’s a must to compile Zig to compile Zig, as a substitute of utilizing Make, CMake, Ninja, meson, and many others. as is typical. Worse is that Zig’s API is being modified continuously, in order that the pattern construct.zig code that I had copied now not labored and needed to be up to date to get the next:
const std = @import("std");
pub fn construct(b: *std.Construct) void {
const goal = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{
.title = "ncurses",
.root_source_file = b.path("predominant.zig"),
.goal = goal,
.optimize = optimize,
});
exe.linkSystemLibrary("c");
exe.linkSystemLibrary("ncurses");
b.installArtifact(exe);
}
With this transformation in place, I now not acquired compile errors for the construct file, however even after deleting the .zig-cache folder that the toolchain creates I saved getting the identical linker errors:
Whereas I’m certain that every one of that is solvable, I used to be in search of an answer to my issues, to not get new issues. As an alternative I acquired a scarcity of robust typing, an oddly verbose syntax, ever-shifting APIs, being strong-armed into giving up the construct instruments of 1’s selecting and eventually some bizarre linker errors that in all probability require fixed nuking of caches as one has to already undergo by means of with CMake and Gradle.
It’s time to zigzag out of dodge to the subsequent language.
Rusted Expectations
As talked about earlier, Rust is just a few years older than Zig, and as well as it has seen much more assist from builders and firms. Its vibrant group is bound to remind you of those information at any alternative they get, together with how Rust cures all ills. Ignoring the plain reminiscence security pink herring, what issues can Rust clear up for us?
Following the identical sample as with Zig, we first must arrange a growth setting with the Rust toolchain and the power to make use of ncurses. Not like with Zig, we apparently can not use C (or C++) code instantly, so the advice is to make use of a wrapper. From its code we are able to worryingly inform that additionally it is a weakly-typed language by means of kind inference, and the truth that the unsafe key phrase is required to cooperate with C interfaces provides even nice trigger for concern. Ideally you’d not do the equal of hammering in uncooked meeting when writing C both, as this bypasses so many checks.
Regardless, the duty is to determine tips on how to use this ncurses-rs wrapper, regardless of it already being EOL-ed. Somewhat than coping with this ‘cargo’ distant repository utility and reliving traumatic reminiscences of distant artefact repositories with NodeJS, Java, and many others., we’ll simply copy the .rs recordsdata of the wrapper instantly into the supply folder of the challenge. It’s usually most popular to have dependencies within the supply tree for safety causes except you have got some degree of assure that the distant supply will likely be accessible and all the time reliable.
Though you should use the rustc compiler instantly, it supplies an especially restricted interface in comparison with e.g. Clang and GCC. After attempting to grasp and therapeutic massage dependency paths for the included recordsdata (modules) for some time, the unhappy result’s all the time one other contemporary sequence of errors, like:

At this level any enthusiasm for doing extra with Rust has already quickly oxidized and decayed into unhappy shards of ferrous oxide.
Workflow Expectations
Most of my publicity to Rust and Zig previous to this expertise had been from a theoretical and extremely academical perspective, however really attempting to make use of a language is if you actually start to develop emotions that inform you whether or not the language is one thing you’re desirous about. In my case these emotions had been for each languages primarily frustration, blended with an urge to get away from the entire thing as quickly as doable.
This contrasts closely with my current experiences with COBOL, which noticed me working for days on code and determining the language, however with a sense of just about giddy pleasure at greedy one more idea or mechanism. What helped so much right here is that the COBOL toolchains are simply typical GCC compilers with the entire function set, which implies that you should use them with any construct system of your selection.
Even with the Ada toolchain and its multi-step strategy of module dependency resolving, compiling and linking you should use these instruments any manner you want. It’s this sort of freedom that’s a minimum of for my part a vital a part of a great growth setting, because it provides the developer the selection of tips on how to combine these into their workflow.
The workflow with Zig and Rust jogs my memory principally of the harrowing wrestle with Android growth and its Gradle-based setting. You get related struggles with simply getting the essential factor off the bottom, are all the time coping with baffling errors that will or might not be associated to a part that’s just a few variations too previous or new, and principally it’s only a gigantic waste of time.
Even ignoring whether or not Zig and Rust are or can turn out to be good languages, it’s this whole disregard for particular person workflow preferences that’s in all probability essentially the most off-putting to me, and motive to keep away from these ecosystems in any respect value. One thing which I want I might do with Gradle as nicely, however I digress.
In the long run I believe I’ll be sticking with C++, with a little bit of C and an rising quantity of Ada and Fortran on the facet. Until you’re being paid huge bucks, there is no such thing as a motive to place your self by means of the struggling of a workflow you detest.

