Uiua プログラミング言語とは
Uiua は BQN 言語に強くインスパイアされた、 Stack based かつ 配列指向 のプログラミング言語です。Kai Schmidt さんが現在は一人で開発を進めているようです。コンパイラの言語には Rust が使われています。GitHubに公開されたのが2023年9月、Initial Commit が2023年2月27日なので、まだ新しい言語です。公式ドキュメントのウェブサイトも Rust で wasm を生成する leptos が使われており、さらにそれを Uiua で書いた HTTP サーバでホストするというサンプルがあります。
Uiua は Rust で書かれているため wasm コンパイルしブラウザ上で動きます。公式サイトでは Playground としてその機能を活用しています。
また Uiua のその他の特徴として、組み込みの関数に視認性の高い Griph 文字を採用していることがあります。Griph の一覧は公式ドキュメントで確認できます。
Griph は関数の効果と対応するように選択されているため、一度覚えて慣れてしまうとコードが圧倒的な情報密度で表現・視認できるという効果があります。通常プログラミングする際は Griph に割り当てられた名前で入力すれば uiua fmt
で Griph に変換が可能です。例えば ↯
という Griph は reshape
という名前を持っており reshape と入力すれば OK です。加えて VSCode に対しては公式で拡張機能が提供されており、それを使えば、ファイル保存をトリガにして自動で Griph 変換を行うことができます。そのため Griph 自体の入力に手間取るというのはあまりありません。既に emacs で動かそうとしている人達もいるので Emacs を使っている方はそちらを参考にしてください。
言語の系統や分類
Uiua は BQN の影響を強く受けていると書きました。 BQN もまた2020年頃に登場したまだ新しい配列指向プログラミングの言語です。 配列指向のプログラミング言語というと 1960年代に登場した APL が有名ですが、ここ数年で BQN → Uiua と新たな言語が開発されており、配列指向プログラミング言語の新たな盛り上がりを感じます。
図の出典こちらの X(Twitter) ポスト: https://twitter.com/code_report/status/1707521763741950003
他のプログラミング言語との特徴の違いはこちらの図が分かりやすいです。
図の出典こちらの GitHub リポジトリ: https://github.com/codereport/array-language-comparisons
Samples
Uiua の威力を感じてもらうため、いくつかの小さなサンプルコードを載せます。
以下のサンプルコードには Griph の視認性をちゃんと感じてもらうため公式が推奨する DejaVu Sans Mono が使われた Playground のスクリーンショットも添えます。また Qiita で Uiua のコードハイライトはサポートされないため、言語指定として代わりに sh
を指定しています1。
Uiua では値は右から順に評価されることに注意してください。
⇡ range
関数による、特定の数値未満の配列の作成
⇡5
# ↓
[0 1 2 3 4]
⇌ revers
関数による、要素の順序反転
⇌⇡5
# ↓
[4 3 2 1 0]
≡ rows
関数による、各要素それぞれの順序の反転
≡⇌ [[1 2 3] [4 5 6]]
# ↓
╭─
╷ 3 2 1
6 5 4
╯
. duplicate
関数による、要素のコピー
. "pullupifipullup"
# ↓
"pullupifipullup"
"pullupifipullup"
要素の完全一致を判定する ≅ match
関数による、回文判定
≅⇌. "pullupifipullup"
# ↓
1
Uiua には Boolean 型に相当するものは今のところないので、真の場合に1
、偽の場合に0
が返ります。
⊞ table
関数による、5x5のマトリックスの二次元配列の作成
↥⇌.⊞=.⇡ 5
# ↓
╭─
╷ 1 0 0 0 1
0 1 0 1 0
0 0 1 0 0
0 1 0 1 0
1 0 0 0 1
╯
⊞ table
は2つの配列の各要素の組み合わせに関数を適用します。
処理内容を順を追って説明します。
·
は noop
という、値をそのまま返す何もしない関数です。アラインを取って見やすくするために挿入してます。
-
······⇡ 5
: 0以上5未満の配列を作成します -
·····.⇡ 5
: その配列をコピーしもう1つ作ります -
···⊞=.⇡ 5
: 2つの同じ配列の全組み合わせを作り、各値は=
による一致判定の結果を入れます。= equals
はまだ紹介していない関数ですが見たまんまなのでたぶん紹介不要でしょう。 -
·⇌.⊞=.⇡ 5
: 出来上がった二次元配列をコピーしもう1つ作り、その中身の順序を反転させます -
↥⇌.⊞=.⇡ 5
:↥ maximum
関数は2つの配列の各要素を比較し大きい方の値を採用し入れ替えます。比較する2つの配列が多次元である場合その要素を再帰的に取り扱います。
まとめ
本当はもっと実用的な大きな処理を書こうと思ったのですが、そこまで説明するのにはまだ結構かかりそうです。需要があれば書きます。
Uiua や スタックベース、配列指向のプログラミングに興味を持たれた方はこちらの環境構築も参考してみてください。
https://zenn.dev/hatappo/articles/e1451b535232a4
公式ドキュメントは充実していますが、私が Rust に慣れないためビルドでは何度かひっかかりました。参考になれば。
-
Uiua の行コメントは
#
なので、そこは sh と共通なのです。sh を指定する理由はそれだけです。 ↩