Rustのトレイト導入時の経緯を紐解く

<!--
# Rust入門者とトレイトとの出会い
Rustを公式チュートリアル（[The Rust Programming Language](https://doc.rust-jp.rs/book-ja/title-page.html)）で学んでいくと、[10.2章](https://doc.rust-jp.rs/book-ja/ch10-02-traits.html)で「トレイト」に出会うことになります。[Smalltalk](https://savannah.gnu.org/projects/smalltalk)や[PHP](https://www.php.net)、[Scala](https://www.scala-lang.org/)等の経験者なら馴染みある言葉かもしれませんが、このチュートリアル10.2章で初めて聞いた、という方も結構多いんじゃないでしょうか（私もそう）。当然トレイトとは何かと気になって調べてみる訳ですが、すると今度は「Rustのトレイトは所謂トレイトではないよ」といった話も出てきたりして（例: [Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%88%E3%83%AC%E3%82%A4%E3%83%88)）、ではRustのトレイトとは一体？という気持ちになってきます。

この点は何人かの方がすでに議論されていて[^a]、素人なりにふんふんと読んでみたりもしたのですが、なにぶん筆者はコンピュータサイエンスの素養がなく、プログラマでもないので、技術面から考察する力はありません。

そこで、ちょっと目線を変えて、歴史的なアプローチから考えてみることにします。というのも、RustはMozillaで生まれ育ったので、開発者同士の会話がメーリングリストのアーカイブとして公開されているのです。このアーカイブを辿れば、Rustにトレイトが導入された当時の開発者同士の会話から、「Rustのトトレイト」の導入経緯・意図を探れるんじゃないかと思った次第です。

-->

# 概要
2011～2013くらい（Rust ver 0.1 - 1.0くらい）の黎明期Rustにおける「トレイト」システムの導入経緯を、当時のMozillaのメーリングリスト等のweb上に残存する記録から簡単に辿ったもの。

# 目的
特になし。別記事を書くためにRustのトレイトまわりの導入経緯について調べていたらボリュームが多くなってしまったので、メモ書き程度にまとめたもの。Rustの開発者たちがどういう意図で現在の「trait」を設計したのか、そのあたりの情報にアクセスする足掛かり程度にはなるかもしれません。

<!--
筆者はRust公式チュートリアル（[The Rust Programming Language](https://doc.rust-jp.rs/book-ja/title-page.html)）を読み進めているRust初心者。[10.2章](https://doc.rust-jp.rs/book-ja/ch10-02-traits.html)で「トレイト」という概念を学んだものの、巷では「Rustのトレイトは所謂トレイトではないよ」といった話もちらほら聞いたりして[^a] [^b]、ではRustの開発者たちはどういう意図でtraitと呼んでいるのか？が気になりました。そこで、Rustにトレイトが導入された当時の開発者同士の会話から「Rustのトレイト」の導入経緯・意図を探れるんじゃないかと思った次第です。
-->
:::note warn
筆者はweb上に残っている記録を拾っただけの素人です。「当時を知る人」でも「コンピューターサイエンスに精通する人」でもないので、もし誤りや漏れ等を見つけた方がいれば、ご指摘を頂けると有難いです。
:::


# Object system redesign
私が見つけた範囲において、Rustの文脈でトレイトが言及された最も古い記録は、Rust 0.1リリースの約1年前、2011年11月にMozillaのメーリングリストに立てられた[Object system redesign（オブジェクトシステムの再構築）」と題されたスレッド](https://mail.mozilla.org/pipermail/rust-dev/2011-November/000929.html)です。[^0]

このスレッドを立てた[Patrick Walton](https://github.com/pcwalton)氏は、それまでのRustのオブジェクトシステムにおける「表現力や開発体験に関わる非常に現実的な問題」として、以下の8点を挙げています。

- 全てのメソッドコールが仮想的である
- 全てのオブジェクトがヒープ上に格納される
- プライベートメソッドが存在しない
- *self*が第一級オブジェクトでない
- パブリックフィールドがない
- 単一継承しかできない
- オブジェクトの拡張に、双方向のvtableの構築が必要
- 型システムが名前的(nominal)でなく構造的(structural)であるため、再帰的になれない

そしてこれらの問題の解決として、`class`, `interface`, そして`trait`の3要素を柱とする新たなオブジェクトシステムを提案しています。これら3つの使い分け方は

- ポリモーフィズム（多相性）が必要な場合は、`interface`を使う
- コードの再利用が必要な場合は`trait`を使う
- どちらでもなければ、単に`class`を使う

とされており、現在のRustにおけるトレイトの役割が`interface`と`trait`に分割されていたようなイメージでしょうか。

この時点では、Rustの生みの親である[Graydon Hoare](https://github.com/graydon)は、「強力なプロポーザルだ」と評しつつも、多くのユーザーを対象とするにはあまりに「heavy」だとして慎重意見を出しています。[^1]

その後categoryシステムやインターフェース/型クラスシステムのプロポーザルが出されたりしていますが、翌2012年の1月の時点で`interface`の実装が進んでいることが報告されています。[^2]　インターフェースを`iface`キーワードで定義し、`impl of [interface] for [type]`でメソッドを実装するという形だったようですね（下記）。

```rust
impl of iter_util<T> for [T] {
     fn len() ->  uint { std::vec::len(self) }
     fn iter(f: block(T)) { for elt in self { f(elt); } }
     fn map<U>(f: block(T) ->  U) ->  [U] {
         let rslt = [];
         for elt in self { rslt += [f(elt)]; }
         rslt
     }
}|
```

# Say that with a traitface

その後の半年感ほど経過を見つけることが出来なかったのですが、2012年7月にGraydon Hoareが新たなロードマップを提示したことが[告知](https://mail.mozilla.org/pipermail/rust-dev/2012-July/002042.html)されます。[^3] その内容が以下の通りです。

> 今週頭にGraydonが送った開発ロードマップの中で、2つの変更が提示されました。「インターフェイスを完全なトレイトへと拡張すること」と「実装のコヒーレンスを強制すること」です。 これらは、**traitとinterfaceを統一**する[このProposal](https://github.com/vadimcn/rust/wiki/Proposal-for-unifying-traits-and-interfaces)によって扱われます。最近、IRCや[Twitter](https://twitter.com/littlecalculist/status/217867708212051969)でたまに「**traitface**」という言葉が使われているように、この作業はすでに始まっています（**安心してください！私たちは実際にそう呼ぶつもりはありません**）。

興味深い表現がいくつか出てきました。まず、「traitとinterfaceを統一」ですが、リンク先のGitHub issueにより詳しい内容が書かれています。

https://github.com/vadimcn/rust/wiki/Proposal-for-unifying-traits-and-interfaces

おおまかな内容は以下の3つです。
- `iface`にデフォルト実装をできるようにする
- `iface`を合成可能（composable）なものにする
- `impl`にコヒーレンスを強制する（1つの`iface`と型のペアにつき、1つの実装しか許さない）

インターフェースをもとに、トレイト由来の機能を足していっている雰囲気があります。[^4]

加えて、「**traitface**」という言葉が出てきました。あくまでも仮称のようですが、[Dave Herman](https://twitter.com/littlecalculist)氏曰く、この時の新しいRust言語のモットーは [**"say that with a traitface（それ、traitfaceで書こうよ）"**](https://twitter.com/littlecalculist/status/217867708212051969)だったそうで、traitでもinterfaceでもなく、それらを足し合わせたものだ、という意識の強さを感じます。（それにしてもすぐに「いやいや勿論こんな名前で呼ぼうとは思ってないから安心してくれよ」みたいなことが書いてあるあたり、ネイティブ的にはtraitfaceってのはよっぽどダサい表現なんですかね？）

実際、"trateface"という呼称は使われることはなく、その後`iface`キーワードが`trait`で置き換えられ、その後の発展を経て現在の形へとつながっていったようです。


# 結論
"traitface"という言葉が出てきたあたり、Rustの開発者たちはRustのtraitを原義に忠実な"trait"のつもりで作った訳ではなさそうである、と感じました。このあたりの用語の定義範囲は人によって差があるとは思いますが。

冒頭で述べたRust公式チュートリアル10.2章ではインターフェースを基にした説明がなされていて、入門者向けにやさしい比喩を使っているのかな、と思っていましたが、上述の経緯を見る限り、案外額面通り受け取っても良いのかもしれません。「Rustのトレイトとは、メソッドのデフォルト実装を書けるインターフェース」という理解で実質的には問題ないと考えられます。

[^a]: https://opaupafz2.hatenablog.com/entry/2022/02/12/100250
[^b]: https://ja.wikipedia.org/wiki/%E3%83%88%E3%83%AC%E3%82%A4%E3%83%88
[^0]: https://mail.mozilla.org/pipermail/rust-dev/2011-November/000929.html
[^1]: https://mail.mozilla.org/pipermail/rust-dev/2011-November/000933.html
[^2]: https://mail.mozilla.org/pipermail/rust-dev/2012-January/001179.html
[^3]: https://mail.mozilla.org/pipermail/rust-dev/2012-July/002042.html
[^4]: この時点では、トレイト内にフィールドを持つか持たないか（いわゆるstatefulかstatelessか）は決まっていなかったようです。一応RFCはありますが: https://github.com/rust-lang/rfcs/pull/1546