2013/04/19

素早くメソッドを逆引き

コンピュータにやらせたい処理はいろいろだと思いますが,
既に関数等の形で提供されているものを使わない手はありません.

その際に障害となるのが,目的の処理を記述したモジュールを探すことです.


最も素早く目的のモジュールを見つける方法は,記憶から引き出すことだと思います. しかし,この方法は目的のモジュールとその名前等の情報をほぼ完全な状態で記憶しておく必要があります. 名前など文脈のない事柄をきちんと記憶することは人間にとって難しい作業であると思います.

ただし,よく使うモジュールであれば,何回も使うため意識しなくとも記憶できるでしょう. たまに使うモジュールであれば,以前使った時の記憶がかすかに残っているでしょう. ちょっと施行錯誤すればすぐ思い出すかもしれませんし, 以前使った時のコードを見て思い出すこともできます.

一方で,全く行ったことのない処理は,探したり・作ったりする必要があります.
この「思い出す」という作業と「探す・作る」という作業の間には, 大きな差があることがわかるでしょうか?

そう,思い出すことはほぼ一瞬であるのに対して,探したり,作ったりすることは時間がかかります.
結局,手元のライブラリをある程度 記憶しておくことが必要であると言えます.


近年多くのIDEで実装されている入力補完機能. この機能が果たす役割は「入力補完」という側面よりも,「記憶の補完」という側面の方が大きいと感じています.

特に日本人は英単語のスペルを覚えることが英語圏の人よりも不得手でしょう. ですが,入力補完機能さえあれば,うろ覚えのスペルでも入力できてしまいます. 2つ目の単語を入力したり,単語の頭文字を順番に入力したりしても,目的の入力候補が見つかるIDEさえあります.
これは,まさに英単語のスペルという記憶を補完していると言えるのではないでしょうか. また,入力候補と一緒にドキュメントを表示する機能も,記憶補完の役に立ちます. そして,最終的には素早いコーディングにつながると思います.


ただし,入力候補から探すにしても,何もない状態から探すにしても, まずはライブラリが無ければ始まりません.
そのライブラリの性質として重要なのは抽象度の高いモジュール群とそれらモジュール同士の直交性です.

抽象度の高いモジュールは楽にコーディングする ために必要な要素であると言えます.
ただし,抽象度のより高いモジュールは,より「ドメイン固有の処理(特定の分野に特化した処理)」になっていくと考えられるため, ライブラリとして用意する場合は,きめ細かな制御ができない・目的に沿わないといった問題や, 多様な問題に対応するためにモジュールのが多くなりがちといった問題が存在します. 特に,モジュール数が多くなってしまっては, その分,記憶しなければならない量が増え,検索の質が低下するため,素早いコーディングにはつながりません.
モジュールは最小限の必要な分だけであるのが望ましいですが.必要最小限かどうかは判断が難しいため, 絶対数等よりも,モジュール同士の直交性に着目した方が賢明でしょう.
経営学で言うところのMECE(Mutually Exclusive and Collectively Exhaustive)のような概念です.


想像してみてください.

足し算のモジュールを 「1を足す」,「2を足す」,…と実装するととんでもない数になります.

こんなのはどうでしょう,
「2つの値を足す」,「3つの値を足す」,…これもキリがなさそうです.
通常は「2つの値を足す」モジュールだけで上記の全ての場合を網羅させると思います.

引き算はどうでしょうか?
「左の値から右の値を引く」モジュールがあればよさそうです.

しかし,足し算において負の数を考慮するなら,「左の値から右の値を引く」モジュールはいらないでしょう.

このように,他のモジュールで簡単にカバーできるモジュール同士は直交性が低いと言います. 逆に全く重複していれば,直交性が高いと言います.



多くのライブラリでは,抽象度と直交性についてよく検討されていることだと思います.
ただし,全ての分野に対応したライブラリ(言語の基本ライブラリ等)は一般化されているため, 抽象度が高いモジュールは少ないことでしょう.また,公開されているものは,インターフェイスの変更が難しいため, 必ずしも最適化されたといえるものでもないかもしれません.
また,解決したい問題があり,そのためのライブラリがあれば利用したいですが, そのライブラリの学習コストも考えなければなりません.
解決したい問題についてよく知らない場合でも,知らない部分だけを隠蔽してくれるライブラリがあれば理想的ですが, 隠蔽しすぎて,できることが制限されている場合もあります.
複雑な処理が必要な場合も,そこだけを隠蔽したモジュールがほしいところです.

結論として,利用するモジュールの抽象度は目的によって選択できるような環境が一番であると言えます.
基本的なモジュールの抽象度は,やはり,言語の基本ライブラリに依存してしまっています.
他のライブラリも抽象度を変えることは難しいでしょう.


そこで,私は自分たち専用のよく使う処理をまとめたライブラリを作るということを提案します.
自分たちで作ったものなら,目的に応じた適度な抽象度を備えることができます.
そして何より覚えやすいと思います.
同じような処理を何度もしているなら,ある程度,直交性を無視してでも,検討してみるとよいでしょう. なぜなら,それはもう抽象度が異なる次元のモジュールかもしれないのですから. 抽象度が異なるモジュールは,上位のモジュールで明確に分離すれば,同じ処理内容でも新たに作る価値は十分あると思います. そうした,小さな改善も積み重なれば,かなりコーディングが速くなるはずです.



さて,では全く行ったことのない処理は,どうやって探したり,作ったりしましょうか? この件についてはまた次の機会に取り上げたいと思います.

0 件のコメント:

コメントを投稿