プログラミング言語Hareを体験してみる
Hareとは
Hareは、2022年に公開されたばかりの比較的新しいプログラミング言語です。シンプル・安定・堅牢であることを目指して開発されているそうで、特に安定・堅牢という点に関しては、最近の言語が実験しているような新機能(ZigのcomptimeやRustのasync/await)には手を出さない保守的な設計によって、50年以上活躍しているC言語に見習った「百年の言語」を目指すと高らかに宣言しています。
コンパイル型で静的型付け、メモリ管理は手動、Go言語のライブラリを参考にしたout-of-the-boxな標準ライブラリを備えています。マクロのようなメタプログラミング機能は敢えて不採用。また、特徴的なのがコンパイラのバックエンドにLLVMではなくQBEを採用している点です。主要開発者のDrew DeVaultさんがインタビューで語っているところによると、QBEはLLVMよりも複雑でないので、プログラマにとって見通しがよく、いろいろなターゲットに移植が容易となるとのこと。
と、ここまで知ったような口ぶり(筆ぶり?)で書いてきましたが、筆者はHareに触れるのは初めてです。この記事では、Hareの開発ツールを揃えた環境を準備して、チュートリアルにあるようなHello World
を実行するところまでを目標とします[1]。
必要ツール/事前知識
本記事ではNixを用いて環境を構築(というほどでもないですが)します。本記事の内容を追試したい場合は、NixのCLIを実行できるようにインストールしてください。Determinate Systemsのインストーラを使うとお手軽だと思います。なお、都度つどコードをコピー&ペーストすれば実行可能なように書くので知識は不要です。
NixはプラットフォームとしてLinuxまたはmacOSを[2]、またHareはLinuxとFree/OpenBSDのみサポートする[3]ので、Windows/macOSの場合はWSL2やDockerを用いてLinux環境を準備してください。
エディタのプラグインも用意されています。筆者はVimのプラグインを導入しました。
環境構築
適当なディレクトリを新規作成しGitリポジトリとします:
$ mkdir hello_hare
$ cd hello_hare
$ git init
$ touch flake.nix
flake.nix
に以下の内容を書き、
{
description = "Hello Hare!";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs?ref=nixpkgs-unstable";
# 知ってる方向け:
# flakelightは簡単な環境構築やパッケージングに便利なflakeで、
# flake-utilsやflake-partsの代わりに使えます。
flakelight = {
url = "github:nix-community/flakelight";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs =
{ flakelight, ... }:
flakelight ./. {
devShell.packages =
pkgs: with pkgs; [
hare # Hareのコンパイラ等、標準ライブラリと環境変数(`HAREPATH`)
haredoc # Hareのドキュメント閲覧ツール
];
devShell.shellHook = pkgs: with pkgs; ''
# MANPATHを通しておく
export MANPATH="${hare.man}/share/man:${haredoc.man}/share/man''${MANPATH:+:''${MANPATH}}"
'';
flakelight.builtinFormatters = false;
};
}
以下のコマンドを実行すると、hare
とharedoc
にパスが通った環境に入ります。
$ git add flake.nix
$ nix develop
[you@your-machine:~/hello_hare]$ harec -v
harec 0.24.0-nixpkgs
[you@your-machine:~/hello_hare]$ echo $HAREPATH
/nix/store/zkl...-hare-0.24.0/src/hare/stdlib
環境変数HAREPATH
はHareの標準ライブラリを参照しており、コンパイル時やharedoc
でドキュメントを閲覧する際に必要となります。
Hello Hare!
準備は整いました。まずはman hare
してみましょう:
hare(1) General Commands Manual hare(1)
NAME
hare - compile, run, test, and inspect Hare programs and modules
SYNOPSIS
hare -h
hare version [-hv]
hare command [arguments...]
DESCRIPTION
hare -h prints help text.
hare version prints version information for the hare program. If -v is supplied,
it also prints information about the build parameters, in an output format that's
consistent for machine reading: the first line is always hare $version, and subse‐
quent lines give configuration values in the form of a name on its own line unin‐
denteed, followed by any number of values, each on its own line indented with a
single tab.
hare-build(1) compiles a Hare program or module.
hare-cache(1) manages the build cache.
hare-deps(1) displays the dependency tree of a Hare program or module.
hare-run(1) compiles and runs a Hare program or module.
hare-test(1) compiles and runs tests for Hare code.
...
おそらくサブコマンドでhare build
やhare test
できるんですね。モダンです。
チュートリアルのGetting startedにあるHello World
(をちょっとだけ変更したコード)を実行してみましょう:
$ cat hello.ha
use fmt;
export fn main() void = {
fmt::println("100年乗っても大丈夫!")!;
};
$ hare run hello.ha
4/4 tasks completed (100%)
100年乗っても大丈夫!
$ hare build -o hello hello.ha
$ ./hello
100年乗っても大丈夫!
余談ですが、どうもZennではHareのシンタックスハイライトをサポートしていないようです。さて、上のHello World
では、fmt
モジュールを利用しています。haredoc
でドキュメントを読んでみましょう:
$ haredoc fmt
// A format string consists of a string of literal characters, to be printed
// verbatim, and format sequences, which describe how to format arguments from a
// set of variadic parameters for printing.
//
// A format sequence is enclosed in curly braces "{}". An empty sequence takes the
// next argument from the parameter list, in order. A specific parameter can be
// selected by indexing it from zero: "{0}", "{1}", and so on. To print "{", use
// "{{", and for "}", use "}}".
//
// ...
ソースコードのコメントをそのまま表示しているだけのようです。このあたりはまだ開発途上ってことかな?
結語
まだ何もやっていないに等しいので、正直まだなんという感想もないのですが、ひとまずHello World
できました。これからしばらくHareで遊んでみようと思います。当初の目的を達成したので本記事はここまでとします。続く!(かも)
Discussion