言語ゲーム

とあるエンジニアが嘘ばかり書く日記

Twitter: @propella

名前空間と最近の悩み

最近ずーっと、Tamacola で使う名前空間について考えている。あるシステムの中で同じ名前の関数を二回以上使いたい時がよくあると思うけど、大まかに二つの解決方法がある。オブジェクトと名前空間だ。オブジェクトというのは、関数をクラスメソッドとして定義する方法。名前空間というのは、関数名をグループ化してグループの名前を前に付けて混ざらないように管理する方法だ。

どちらも一種の辞書なのでよく似ている。実際、Python のパッケージはオブジェクトで実装されているし、JavaScript ではオブジェクトを名前空間として使うのが常套句になっている。ただわざわざ名前空間と言うとき、コンパイル時に名前の意味が決定出来るものを言うようだ。

悩みというのは、関数名の整理にオブジェクトか名前空間のどちらを使おうかという事だ。メジャーなオブジェクト指向言語では名前空間を使ってクラスを管理し、クラスメソッドとしてさらに関数を整理するけど、ややこしいのでどちらかにしたい。つまり、Squeak のように名前空間無しでクラスだけか、R6RS のように名前空間だけあってクラス無しか。

オブジェクト/クラス式の利点は差分プログラミングをサポートしている点だ。

差分プログラミングというのは、オブジェクトを使うとあるクラス A をちょっとだけ変更したクラス B を簡単に作れるという機能だ。名前空間だけを使っても、名前空間 A を名前空間 B で利用するという事は出来るのだけど、A の内容をちょこっと変更するテンプレートパターンみたいな事は出来ない(A の中の関数が再定義した B の関数を自動的に呼ぶという事は無い)。ちょこっと変更をやろうとすると、変更する部分をあらかじめパラメータ化しておくという事になる。

一方で、オブジェクトだとまずい事がある。ちょこっと変更出来るという事はある意味スーパークラス側のカプセル化が弱いという事なので、変更する時は十分気を使わないといけない。また名前の意味が実行時まで分からないのでマクロと相性が悪い。

この問題について二週間くらい心が揺れ動いていて何も手を付けられないでいたけど、今はより窮屈な名前空間を選ぼうと思っている。というのも、名前空間の方が原始的な機能なのであとでオブジェクト式に変更する事は簡単だろうという事と、オブジェクトの便利な機能を使わないでどこまで簡潔に書けるか興味があるからだ。

実はここ一年ほど、ほとんどオブジェクト指向言語の機能、特に継承を使わずに生きてみて、オブジェクト指向の良し悪しについて考えていた。オブジェクト指向は便利な機能だけど、http://d.hatena.ne.jp/propella/20090622/p1 に書いたようにたまに強力すぎると思う事がある。強力すぎる物は、ある目的には最強だけど、うまくはまらない場面では無駄な複雑さを生む。

また、たまにクラスメソッドを多用するプログラマを馬鹿だと批判して荒れる掲示板があるけど、そもそもオブジェクトを名前空間のようにしか使えないプログラマが沢山いるという事は、プログラマが馬鹿なんじゃなくてオブジェクト指向の中に不自然な心理モデルを強制する物があるんじゃないかと最近疑っている。

この考えをはっきりさせるために、こんな場面ではオブジェクト指向を使ってはいけない!とか、オブジェクト指向を使わなくてもこんなに綺麗に書ける!というのを考えようと思っているので、もうしばらくオブジェクトからは距離を置こうと最近思うのでした。