すでにC++、D、Rustがあるのに、なぜZigなのか?

隠れた制御フローなし

もしZigのコードが関数を呼び出すために飛び出しているように見えないなら、それは違うのです。つまり、次のコードはfoo()bar()のみを呼び出し、何も型を知らなくてもこれが保証されていることを意味します:

var a = b + c.d;
foo();
bar();

隠れた制御フローの例:

この設計上の判断の目的は、可読性を向上させることです。

隠れたアロケーションなし

Zigはヒープ割り当てに関しては、ハンズオフ・アプローチを採用しています。 newキーワードや、ヒープアロケータを使用する他の言語機能(例: 文字列連結演算子[1])は存在しないです。 ヒープの概念全体は、言語ではなく、ライブラリとアプリケーションのコードによって管理されます。

隠れたアロケーションの例:

ガベージコレクタはクリーンアップ側で証拠を隠すので、 ほぼすべてのガベージコレクタ言語には隠れたアロケーションが散見されます。

隠れアロケーションの主な問題は、コード片の再利用性を妨げ、コードが展開されるのに適した環境の数を不必要に制限してしまうことです。 簡単に言えば、制御フローや関数呼び出しがメモリ割り当ての副作用を持たないことを保証しなければならないユースケースがあります。 したがって、プログラミング言語は現実的にこの保証を提供できる場合にのみ、 このユースケースに対応することができるのです。

Zigの場合、ヒープアロケータを提供し動作させる標準ライブラリ機能がありますが、 それはオプションの標準ライブラリ機能であり、言語自体に組み込まれているわけではありません。 ヒープアロケータを決して初期化しなければ、プログラムがヒープアロケートをしないことを確信できます。

ヒープメモリを確保する必要がある標準ライブラリの機能はすべて、それを行うためにAllocatorパラメータを受け取ります。 これは、Zig標準ライブラリが独立したターゲットをサポートしていることを意味する。例えば、std.ArrayListstd.AutoHashMapはベアメタルプログラミングに使用することができます!

カスタムアロケーターを使えば、手動でのメモリ管理も楽になります。 Zigにはデバッグアロケータがあり、use-after-freeやdouble-freeに直面しても、メモリの安全性を維持することができます。 メモリリークを自動的に検出してスタックトレースを表示する。 アリーナアロケータがあり、いくつものアロケーションを1つに束ねそれぞれのアロケーションを個別に管理するのではなく、 一度にすべて解放することができます。特殊用途のアロケータは特定のアプリケーションのニーズに合わせて、 パフォーマンスやメモリ使用量を改善するために使用することができます。

[1]:実は文字列連結演算子(一般的には配列連結演算子)はあるのですが、コンパイル時にしか動作しないので、やはり実行時のヒープ確保はしてくれません。

標準ライブラリがない場合のファーストクラスのサポート

上で述べたように、Zigには完全にオプションの標準ライブラリがあります。 各標準ライブラリのAPIは、それを使う場合にのみプログラムにコンパイルされます。 Zigはlibcとリンクすることも、リンクしないことも同じようにサポートします。 Zigはベアメタルやハイパフォーマンスな開発に適しています。

例えばZigでは、WebAssemblyのプログラムは標準ライブラリの通常の機能を利用しながら、 WebAssemblyへのコンパイルをサポートする他のプログラミング言語と比較して、 最も小さなバイナリを生成することができるのです。

ライブラリのためのポータブル言語

プログラミングの聖杯の1つは、コードの再利用です。しかし悲しいことに、実際には何度も何度も車輪の再発明を繰り返していることに気づきます。多くの場合、それは正当化されています。

既存プロジェクトのためのパッケージマネージャとビルドシステム

Zigはプログラミング言語ですが、従来のC/C++プロジェクトの文脈でも有用であることを意図したビルドシステムとパッケージマネージャを同梱しています。

CやC++のコードの代わりにZigのコードを書けるだけでなく、autotools、cmake、make、scons、ninjaなどの代わりとしてZigを使うことができます。その上、ネイティブな依存関係のためのパッケージマネージャを提供する(予定)です。このビルドシステムは、プロジェクトのコードベース全体がCまたはC++であっても適切であることを意図しています。

apt-get、pacman、homebrew などのシステムパッケージマネージャはエンドユーザにとって便利なものですが、開発者のニーズには不十分な場合があります。言語固有のパッケージマネージャは、コントリビュータがいない場合と多い場合の違いになり得ます。オープンソースプロジェクトでは、プロジェクトをビルドすることの難しさは、潜在的コントリビュータにとって大きなハードルとなっています。C/C++のプロジェクトでは、依存関係があることは致命的で、特にWindowsではパッケージマネージャがありません。Zig自体をビルドする場合でさえ、ほとんどの潜在的コントリビュータはLLVMの依存関係で苦労しています。Zigは、プロジェクトがネイティブ・ライブラリに直接依存する方法を提供しています(今後提供する予定です)。

Zigは、プロジェクトのビルドシステムを、宣言的なAPIを使った合理的な言語に置き換え、パッケージ管理も提供し、他のCライブラリに実際に依存できるようにすることを提案している。依存関係を持つことで、より高度な抽象化が可能になり、再利用可能な高レベルのコードの普及が期待できます。

シンプルさ

C++、Rust、Dは機能が多すぎて、作業しているアプリケーションの実際の意味から逸れてしまうことがあります。アプリケーションをデバッグするのではなく、プログラミング言語の知識をデバッグしている自分に気がつくのです。

Zig にはマクロもメタプログラミングもありませんが、それでも複雑なプロ グラムを明確かつ繰り返しのない方法で表現するには十分強力です。Rust でさえ、format! のような特殊なケースを持つマクロがあり、これはコンパイラ自体に実装されています。一方Zigでは、同等の関数が標準ライブラリに実装されており、コンパイラに特殊なケースのコードはありません。

ツール

Zigはダウンロードセクションからダウンロードすることができます。Zigは、Linux、Windows、macOS、FreeBSD用のバイナリアーカイブを提供しています。以下は、これらのアーカイブの1つで得られるものについて説明しています: