Rustとクトゥルフ神話

この記事は[ドワンゴ Advent Calendar 2024](https://qiita.com/advent-calendar/2024/dwango)の12日目の記事です。

## はじめに

[H・P・ラヴクラフト](https://ja.wikipedia.org/wiki/%E3%83%8F%E3%83%AF%E3%83%BC%E3%83%89%E3%83%BB%E3%83%95%E3%82%A3%E3%83%AA%E3%83%83%E3%83%97%E3%82%B9%E3%83%BB%E3%83%A9%E3%83%B4%E3%82%AF%E3%83%A9%E3%83%95%E3%83%88)はアメリカの小説家で、「クトゥルフ神話」の創始者として知られています。
クトゥルフ神話とは（解説する必要もないほど有名ですが）、ラヴクラフトの小説「クトゥルー[^7]の呼び声」を発端とするシェアード・ワールドです。
かつて地球を支配した邪神にまつわる<ruby>宇宙的恐怖<rp>(</rp><rt>コズミック・ホラー</rt><rp>)</rp></ruby>やゴシック的懐古趣味、はたまたSF的な要素が組み合わされた世界観が特徴で、いまはTRPGの展開も有名ですね。

さてここでは、ラヴクラフトとRustにまつわる小話を紹介します。

## ランタイムを覆う影[^1]

### さまざまなイースターエッグ

本題に入る前に、まず[イースターエッグ](https://ja.wikipedia.org/wiki/%E3%82%A4%E3%83%BC%E3%82%B9%E3%82%BF%E3%83%BC%E3%82%A8%E3%83%83%E3%82%B0_(%E9%9A%A0%E3%81%97%E8%A6%81%E7%B4%A0))について見ておきましょう。
IT用語としてのイースターエッグとは、ソフトウェアに隠された、それ本来の目的とは関係ない隠し要素のことです。
一般に有名なものとしては、たとえば、Googleの検索画面にはいくつものイースターエッグが仕込まれています。
- 「一回転」を検索すると一回転する
- 「再帰」と検索すると「もしかして: 再帰」がサジェストされる

などですね。

より技術寄りの例としては、vimで`:help 42`というコマンドを入力すると、[生命、宇宙、その他もろもろについての深淵なる疑問の答え](https://ja.wikipedia.org/wiki/%E7%94%9F%E5%91%BD%E3%80%81%E5%AE%87%E5%AE%99%E3%80%81%E3%81%9D%E3%81%97%E3%81%A6%E4%B8%87%E7%89%A9%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%81%AE%E7%A9%B6%E6%A5%B5%E3%81%AE%E7%96%91%E5%95%8F%E3%81%AE%E7%AD%94%E3%81%88)をふくむテキストが表示されます[^2]。

```plaintext
What is the meaning of life, the universe and everything?  *42*
Douglas Adams, the only person who knew what this question really was about is
now dead, unfortunately.  So now you might wonder what the meaning of death
is...

==============================================================================

Next chapter: |usr_43.txt|  Using filetypes

Copyright: see |manual-copyright|  vim:tw=78:ts=8:noet:ft=help:norl:
```

また、プログラミング言語そのものにイースターエッグが仕込まれていることもあります。たとえばpythonのREPLを起動して
```bash
>>> import this
```
を実行すると、有名な "The Zen of Python" が出力されます。

```plaintext
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
```

余談ですが、`this`モジュールの実装はかなり奇妙です。気になる方は、
```bash
>>> import inspect
>>> inspect.getsource(this)
```
などで確認してみてください[^3]。

### Rustのイースターエッグ

ひるがえってRustではどうでしょうか。
現在のRustにはマイナーないくつかのイースターエッグがあります。
わたしが確認した範囲だと、
- [test-dummy-unstable](https://doc.rust-lang.org/cargo/reference/unstable.html)に関連して`im-a-teapot`[^15]というオプションが定義されている[^8]
- 🦀を変数名に用いると特別なエラーメッセージが出力される
    - `let 🦀 = '🦀'`と定義してコンパイルすると、`Ferris cannot be used as an identifier`というエラーになる

などが見つかりました。
一方で、廃止されてしまったものもあります。かつてRustでは、Runtimeのabort時にラヴクラフト作品の引用が出力されていました。

https://github.com/rust-lang/rust/issues/13871

表示される引用文はいくつかの候補から選ばれるようになっており、たとえば0番目は「クトゥルーの呼び声」の一節です。

> It was from the artists and poets that the pertinent answers came, and I
know that panic would have broken loose had they been able to compare notes.
As it was, lacking their original letters, I half suspected the compiler of
having asked leading questions, or of having edited the correspondence in
corroboration of what he had latently resolved to see.

> 適切な回答は芸術家や詩人たちから来たもので、もし彼らが回答を比較できていたなら<ruby>パニック<rp>(</rp><rt>panic</rt><rp>)</rp></ruby>が起こっていただろう。
実のところ、回答の原文が残っていなかったため、私は<ruby>編纂者<rp>(</rp><rt>コンパイラ</rt><rp>)</rp></ruby>の質問が誘導的でなかったか、あるいは彼が無意識に予見していたものを裏づけるために回答を編集したのではなかったか、と半ば疑っていた[^5]。

`panic`やコンパイラ[^4]など、プログラミングらしいワードが登場する気の利いた引用ですね[^13]。

これらの引用は、標準ライブラリにおいて約2KBの容量を占め、Hello Worldのような基礎的なプログラムにさえ含まれてしまうことが問題視され、Rustから削除されてしまいました。

## <ruby>PR<rp>(</rp><rt>プルリク</rt><rp>)</rp></ruby>に乗りて歩むもの[^11]

### Spoon

さて、Rustを追われたラヴクラフトは、じつは他のOSSプロジェクトで生きのびています。
[spoon](https://spoon.gforge.inria.fr/)[^6]というJavaの静的解析ツールに存在する、[`LovecraftException`](https://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/LovecraftException.html)クラスを見てみましょう[^9]。

 ```java
 /*
 * SPDX-License-Identifier: (MIT OR CECILL-C)
 *
 * Copyright (C) 2006-2023 INRIA and contributors
 *
 * Spoon is available either under the terms of the MIT License (see LICENSE-MIT.txt) or the Cecill-C License (see LICENSE-CECILL-C.txt). You as the user are entitled to choose the terms under which to adopt Spoon.
 */
package spoon;

/**
 * "It was from the artists and poets that the pertinent answers came"
 *
 * In Spoon, we do believe that poetry has a place in software.
 *
 * This class counters the dark side of the force which won at https://github.com/rust-lang/rust/issues/13871
 */
public class LovecraftException extends SpoonException {
	private static final long serialVersionUID = 1L;

	public static final String lovecraft =
		"It was from the artists and poets that the pertinent answers came, and I\n"
		+ "know that panic would have broken loose had they been able to compare notes.\n"
		+ "As it was, lacking their original letters, I half suspected the compiler of\n"
		+ "having asked leading questions, or of having edited the correspondence in\n"
		+ "corroboration of what he had latently resolved to see."
		+ "There are not many persons who know what wonders are opened to them in the\n"
		+ "stories and visions of their youth; for when as children we listen and dream,\n"
		+ "we think but half-formed thoughts, and when as men we try to remember, we are\n"
		+ "dulled and prosaic with the poison of life. But some of us awake in the night\n"
		+ "with strange phantasms of enchanted hills and gardens, of fountains that sing\n"
		+ "in the sun, of golden cliffs overhanging murmuring seas, of plains that stretch\n"
		+ "down to sleeping cities of bronze and stone, and of shadowy companies of heroes\n"
		+ "that ride caparisoned white horses along the edges of thick forests; and then\n"
		+ "we know that we have looked back through the ivory gates into that world of\n"
		+ "wonder which was ours before we were wise and unhappy."
		+ "Instead of the poems I had hoped for, there came only a shuddering blackness\n"
		+ "and ineffable loneliness; and I saw at last a fearful truth which no one had\n"
		+ "ever dared to breathe before — the unwhisperable secret of secrets — The fact\n"
		+ "that this city of stone and stridor is not a sentient perpetuation of Old New\n"
		+ "York as London is of Old London and Paris of Old Paris, but that it is in fact\n"
		+ "quite dead, its sprawling body imperfectly embalmed and infested with queer\n"
		+ "animate things which have nothing to do with it as it was in life."
		+ "The ocean ate the last of the land and poured into the smoking gulf, thereby\n"
		+ "giving up all it had ever conquered. From the new-flooded lands it flowed\n"
		+ "again, uncovering death and decay; and from its ancient and immemorial bed it\n"
		+ "trickled loathsomely, uncovering nighted secrets of the years when Time was\n"
		+ "young and the gods unborn. Above the waves rose weedy remembered spires. The\n"
		+ "moon laid pale lilies of light on dead London, and Paris stood up from its damp\n"
		+ "grave to be sanctified with star-dust. Then rose spires and monoliths that were\n"
		+ "weedy but not remembered; terrible spires and monoliths of lands that men never\n"
		+ "knew were lands..."
		+ "There was a night when winds from unknown spaces whirled us irresistibly into\n"
		+ "limitless vacuum beyond all thought and entity. Perceptions of the most\n"
		+ "maddeningly untransmissible sort thronged upon us; perceptions of infinity\n"
		+ "which at the time convulsed us with joy, yet which are now partly lost to my\n"
		+ "memory and partly incapable of presentation to others."
		+ "You've met with a terrible fate, haven't you?";

	public LovecraftException(String message) {
		super(lovecraft + "\n" + message);
	}
}
 
 ```

Rustで削除された引用が、このクラスにまるごと移植されていることがわかります。
個人的には、このクラスがExceptionとして実装されている点にJavaらしさを感じます[^14]。

さらにこぼれ話として、このクラスには実用例（！）があります。
Spoonのコード中で、例外を投げる処理が[一箇所だけ`LovecraftException`に置き換えられている](https://github.com/INRIA/spoon/blob/9baf35f83dcf4325e4a2670b5aa697a272cff4eb/src/main/java/spoon/support/reflect/code/CtLambdaImpl.java#L275) のです。
`In Spoon, we do believe that poetry has a place in software.`というコメントをまさに実行していますね[^10]。エラーメッセージの`A lambda can't have two bodies.`も、どこか文学的に見えてきます。

## おわりに

昨今では、品質管理の観点から、開発者の遊び心によってソフトウェアになにかを仕込む機会はなくなってきているように思います。
それ自体は当然の流れではありますが、たまにはOSSでしぶとく生きながらえるこういった要素を愛でてみるのもよいかもしれません。

> かくのごとき偉大な力や存在については、あるいは生きながらえているものがいるのかもしれない……永劫の太古から生きながらえているのかもしれない……おそらく太古には意識が姿や形に体現していたのであって、進展する人類の絶頂期をまえに退いて久しいとはいえ……そうした姿はわずかに詩と伝説のみがうつろいゆく記憶をとらえ、それらを神々、怪物、ありとあらゆるたぐいの神話の生物と呼び……
>
> アルジャーノン・ブラックウッド[^12]



[^1]: [インスマスを覆う影](https://ja.wikipedia.org/wiki/%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%9E%E3%82%A6%E3%82%B9%E3%81%AE%E5%BD%B1)
[^2]: 説明する必要もないほど有名かもしれませんが、補足しておきます。「生命、宇宙、その他もろもろについての深淵なる疑問の答え」が「`42`」だというのは、名作SF「銀河ヒッチハイク・ガイド」に登場するエピソードです。超知性を備えた汎次元生物であるところの*ねずみ*が開発したスーパーコンピュータ「ディープ・ソート」が750万年かけて導き出した答えが「`42`」でした。
[^3]: [Github](https://github.com/python/cpython/blob/main/Lib/this.py)でも閲覧できます。The Zen of Pythonの文章が[ROT13](https://ja.wikipedia.org/wiki/ROT13)で"暗号化"されていますね。ROT13は分類としてはシーザー暗号の一種で、変換を2回適用すると元に戻るというちょっとおもしろい特徴があります。
[^4]: 原文における "compiler" は、手紙を集めて整理していた主人公の大叔父を指しています。compilerといえば、プログラミングにおける意味でしか使ったことがなかったですが、すくなくともラヴクラフトの語彙にはあったんですね。
[^5]: 翻訳は筆者。
[^6]: 筆者はこのOSSを業務で使っていたことがあり、3行ぐらいコミットしたこともあります。逆にこちらからRustのイースターエッグのことを知りました。
[^7]: 「クトゥルフ」との表記揺れがありますが、わたしは青心社の「暗黒神話体系シリーズ　クトゥルー」を愛読していたのでこちらの表記にします。
[^8]: こちらは、厳密にいうとRust本体ではなくてcargoのイースターエッグですが。
[^9]: [MITライセンス](https://github.com/INRIA/spoon/blob/master/LICENSE-MIT.txt)のもとに掲載します。
[^10]: ちなみに、[commit](https://github.com/INRIA/spoon/commit/c4a37b0eb19a807cf96f84dc47f5a1f5eabb226f)メッセージも`fix: poetry has a place in software`となっています。
[^11]: [風に乗りて歩むもの](https://ja.wikipedia.org/wiki/%E3%82%A4%E3%82%BF%E3%82%AB)
[^12]: H.P.ラヴクラフト「クトゥルーの呼び声」のエピグラフより。
[^13]: 他にプログラミング的な文言があるか探してみましたが、3番目の引用文にある"terrible spires and <ruby>monoliths<rp>(</rp><rt>モノリス</rt><rp>)</rp></ruby>"ぐらいでしょうか。
[^14]: Javaにおける例外が、検査例外・非検査例外にまつわる考え方など、よくも悪くもJavaらしさを感じさせる部分だからかもしれません。
[^15]: `im-a-teapot`はそれ自体がまたイースターエッグで、「[サーバーが、自身がティーポットであることを理由としてコーヒーを入れることを拒否する](https://developer.mozilla.org/ja/docs/Web/HTTP/Status/418)」ことを示すHTTPステータスコードです。