Independent versioning of the language and standard library

I love C and Zig because the standard library is an option. When needed, you can change it or even write some assembly code by hand. This makes the C indispensable outside the OS.

On the other hand, a significant problem for C, C++, Rust and other has been bugs in the standard library: functions with hidden allocations, functions without bounds checking, and so on. Many things are simply poorly designed (like std::vector<bool>) that can’t be fixed without a language version upgrade.

Even backwards compatibility issues in new versions of Zig usually stem from the standard library (hello, std.Io).

An alternative is to make the standard library a regular tier 1 dependency, just developed by the official team.

In this case, updating the compiler and updating the library are different tasks. The library is updated more frequently, can be used together in alternative compilers, and has weaker compatibility guarantees. The language, on the other hand, is updated only when new language features are introduced (like async/await, borrow checkers, or changes to the type system).

A potential downside is the requirement to work with different libraries (lib1 depends on stdlib@1.1, lib2 on stdlib@1.2), but we’re addressing this issue for any dependencies anyway.

Is there an elephant in the room I’m missing?

At the time the std lib is mostly a collection of things to compiler itself uses. The compiler of the master branch relies on the std lib of the master branch and the std lib of the master branch uses features from the of the master branch.

AFAIK the compiler itself depends heavily on the stdlib (to a point where one could say that the stdlib mainly exists for the needs of the compiler, and important parts of a Zig toolchain are also in the stdlib (like the build system and package manager).

E.g. there might be a chicken-egg-problem.

One useful strategy might be to keep the stdlib itself as minimal as possible (only the things needed by the compiler) and put the ‘batteries’ into regular ‘sanctioned-by-the-core-team’ packages.

2 Likes

Do you mean that some syntax depend on the standard library (like lambdas in C++, something like sanitizers and stack unfolding?) or that the compiler itself is compiled with standard library code?

It seems the second isn’t a problem at all; it’s a matter of the compiler’s build system.

In the first case, it seems you’re right but only a small subset is needed, without IO, allocators, networking, etc.

1 Like

Zig ships some of its compiler internals as source code, living in std.zig. There’s an open proposal to expand it. The build system is also mostly (entirely?) Zig source code living in the standard library.

In that sense you can’t update the compiler without updating the standard library, because a chunk of the compiler is in the standard library and depends on the functions in it.

1 Like

And obviously there’s std.builtin. In theory, that namespace could be moved to the root level, but then we’d end up with an additional quasi-mandatory import (beside std itself).

1 Like