スタックベースの 配列プログラミング言語 - Uiua

### Uiua プログラミング言語とは


Uiua は [BQN](https://mlochbaum.github.io/BQN/) 言語に強くインスパイアされた、 Stack based かつ 配列指向 のプログラミング言語です。[Kai Schmidt さん](https://github.com/kaikalii)が現在は一人で開発を進めているようです。コンパイラの言語には Rust が使われています。GitHubに公開されたのが2023年9月、[Initial Commit が2023年2月27日](https://github.com/uiua-lang/uiua/commit/dc6425944e28d08c6a7c69ec4957041e9c1147e5)なので、まだ新しい言語です。公式ドキュメントのウェブサイトも Rust で wasm を生成する [leptos](https://leptos.dev/) が使われており、さらにそれを Uiua で書いた HTTP サーバでホストするという[サンプル](https://github.com/uiua-lang/uiua/blob/main/examples/http_server.ua)があります。

Uiua は Rust で書かれているため wasm コンパイルしブラウザ上で動きます。公式サイトでは Playground としてその機能を活用しています。

![スクリーンショット 2023-10-01 22.27.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37466/9405634d-957c-4216-279d-d050f21d1f19.png)

また Uiua のその他の特徴として、組み込みの関数に視認性の高い Griph 文字を採用していることがあります。Griph の一覧は[公式ドキュメント](https://www.uiua.org/docs)で確認できます。

![スクリーンショット 2023-10-01 22.06.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37466/66ac4abc-6e63-8bb5-83a2-c80bd0ec7986.png)

Griph は関数の効果と対応するように選択されているため、一度覚えて慣れてしまうとコードが圧倒的な情報密度で表現・視認できるという効果があります。通常プログラミングする際は Griph に割り当てられた名前で入力すれば `uiua fmt` で Griph に変換が可能です。例えば `↯` という Griph は `reshape` という名前を持っており reshape と入力すれば OK です。加えて VSCode に対しては公式で[拡張機能](https://marketplace.visualstudio.com/items?itemName=uiua-lang.uiua-vscode)が提供されており、それを使えば、ファイル保存をトリガにして自動で Griph 変換を行うことができます。そのため Griph 自体の入力に手間取るというのはあまりありません。既に [emacs で動かそうとしている人達](https://github.com/uiua-lang/uiua/issues/13)もいるので Emacs を使っている方はそちらを参考にしてください。

### 言語の系統や分類

Uiua は BQN の影響を強く受けていると書きました。 BQN もまた２０２０年頃に登場したまだ新しい配列指向プログラミングの言語です。 配列指向のプログラミング言語というと 1960年代に登場した APL が有名ですが、ここ数年で BQN → Uiua と新たな言語が開発されており、配列指向プログラミング言語の新たな盛り上がりを感じます。

![F7JVHKvXMAAi2RZ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37466/e7b8c17d-3791-38ff-ed93-21973f877254.png)

図の出典こちらの X(Twitter) ポスト： https://twitter.com/code_report/status/1707521763741950003

他のプログラミング言語との特徴の違いはこちらの図が分かりやすいです。

![270837375-13f7164e-d9ea-4c7c-a211-bd437d51949c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37466/adcc015c-7378-15d6-4c02-95303060b57f.png)

図の出典こちらの GitHub リポジトリ： https://github.com/codereport/array-language-comparisons


### Samples

Uiua の威力を感じてもらうため、いくつかの小さなサンプルコードを載せます。
以下のサンプルコードには Griph の視認性をちゃんと感じてもらうため公式が推奨する [DejaVu Sans Mono](https://dejavu-fonts.github.io/) が使われた Playground のスクリーンショットも添えます。また Qiita で Uiua のコードハイライトはサポートされないため、言語指定として代わりに `sh` を指定しています[^1]。

Uiua では値は右から順に評価されることに注意してください。

#### `⇡ range` 関数による、特定の数値未満の配列の作成

![スクリーンショット 2023-10-01 22.40.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37466/26d63c5e-b320-40f2-cb1b-0d1c151746fe.png)

```sh
⇡5
# ↓
[0 1 2 3 4]
```

#### `⇌ revers` 関数による、要素の順序反転

![スクリーンショット 2023-10-01 22.41.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37466/02fa69dd-37d7-8c0a-06fe-305d06abe984.png)

```sh
⇌⇡5
# ↓
[4 3 2 1 0]
```

#### `≡ rows` 関数による、各要素それぞれの順序の反転

![スクリーンショット 2023-10-01 22.44.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37466/8a781cea-20ad-7714-6143-dd2de3012228.png)

```sh
≡⇌ [[1 2 3] [4 5 6]]
# ↓
╭─       
╷ 3 2 1  
  6 5 4  
        ╯
```

#### 　`. duplicate` 関数による、要素のコピー

![スクリーンショット 2023-10-01 22.49.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37466/f08f48ee-d4db-dad8-d5d6-9cd34cea5e22.png)

```sh
. "pullupifipullup"
# ↓
"pullupifipullup"
"pullupifipullup"
```

#### 要素の完全一致を判定する `≅ match` 関数による、回文判定

![スクリーンショット 2023-10-01 23.09.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37466/3e674c86-7d41-96c0-bb4f-d42f69542432.png)

```sh
≅⇌. "pullupifipullup"
# ↓
1
```

Uiua には Boolean 型に相当するものは今のところないので、真の場合に`1`、偽の場合に`0`が返ります。

#### `⊞ table` 関数による、５ｘ５のマトリックスの二次元配列の作成

![スクリーンショット 2023-10-03 15.18.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37466/095f4e4f-4425-f426-ae0d-4a5d5c344f7e.png)

```sh
↥⇌.⊞=.⇡ 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` という、値をそのまま返す何もしない関数です。アラインを取って見やすくするために挿入してます。

1. `······⇡ 5`: 0以上５未満の配列を作成します
1. `·····.⇡ 5`: その配列をコピーしもう1つ作ります
1. `···⊞=.⇡ 5`: ２つの同じ配列の全組み合わせを作り、各値は `=` による一致判定の結果を入れます。`= equals` はまだ紹介していない関数ですが見たまんまなのでたぶん紹介不要でしょう。
1. `·⇌.⊞=.⇡ 5`: 出来上がった二次元配列をコピーしもう1つ作り、その中身の順序を反転させます
1. `↥⇌.⊞=.⇡ 5`: `↥ maximum` 関数は２つの配列の各要素を比較し大きい方の値を採用し入れ替えます。比較する2つの配列が多次元である場合その要素を再帰的に取り扱います。


### まとめ

本当はもっと実用的な大きな処理を書こうと思ったのですが、そこまで説明するのにはまだ結構かかりそうです。需要があれば書きます。

Uiua や スタックベース、配列指向のプログラミングに興味を持たれた方はこちらの環境構築も参考してみてください。
https://zenn.dev/hatappo/articles/e1451b535232a4
公式ドキュメントは充実していますが、私が Rust に慣れないためビルドでは何度かひっかかりました。参考になれば。

[^1]: Uiua の行コメントは `#` なので、そこは sh と共通なのです。sh を指定する理由はそれだけです。