トレイトを勉強していたらクラスの定義の食い違いに気づいた話
以前自分が書いた記事Scalaのtraitはmixinか?を元に、トレイトに関する補足記事を書こうとして「そうだ、どうせならば元論文の記述とも照らしあわせたほうがよいな」と「Traits: A Mechanism for Fine-grained Reuse」を読んだ。そこで気づいたのだけども、この件に関して意見が咬み合わないことがあるのは、そもそも「クラス」の定義に食い違いがあるせいではないか?
「Traits: A Mechanism for Fine-grained Reuse」での定義ではクラスとは「空クラスnil」もしくは「属性の集合と、メソッドの集合と、親クラス」と定義されている*1
で、トレイトとは「メソッドの集合」と定義されている*2
これがどういうことかというと、トレイトなどから作られたクラスは「自分を構成するのにどういうトレイトが使われたか」という情報を持たないってことなんだ。なのでsuperはトレイトに対して何も特別な挙動をしない。クラスの中からsuperした際にはusesしてるトレイトのことは考えないし、トレイトのメソッドからusesした時はそのメソッドが元々トレイトの中にあったという情報とはまったく無関係に「そのトレイトがいまusesされているクラス」の親クラスを指すわけだ。
僕のクラスのメンタルモデルはPythonに慣れているので「属性の集合と、メソッドの集合と、複数の親クラスへの参照」になっていて、それがトレイトを学んだ際に「属性の集合と、メソッドの集合と、1個の親クラスへの参照と、0個以上のトレイトへの参照」へと更新されたのだけども、それはトレイトを提案した人たちの定義とは食い違っていたということだ。
この辺りの話は以前id:sumimさんがブログに書かれていたように思うけども、「平坦化」とかで検索しても見つけられず…。
追記: あった: Scalaのトレイトは実はトレイトじゃなくただのミクスイン - Smalltalkのtは小文字です 「リニア化」と「フラット化」だった。