メタファーを身につけてプログラミングの生産性を向上させる
インターナショナルチームでプログラミングの仕事をしていると、いろんなところで同僚との差を感じてしまう。いろんな国の人がいて、レベルは人によりそれぞれなんだけど、一般的にいうと、アメリカのプログラマのレベルは平均してとても高い場合が多い。とにかくコードがきれいでシンプルで仕事が早い。
彼らがなぜそれができるのかを観察しているが、一つ気が付いたことについてその対策も含めて書いてみたい。
彼らがプログラマとして優れているところ
USにいるとお客様の技術レベルが高いとか、新しいことにチャレンジするとかいろいろ要素はあるのだけど、個人の生産性、コードの美しさをみても、平均値を観察するとアメリカの人が一番に感じる。その他にも、ドキュメントを見てすぐ理解できる能力は、アメリカの人はおろか、ヨーロッパ圏やインドの人と比べても、私は圧倒的に負けていると感じる。
Williams 衝撃の読解力
新しいライブラリを学習しようと思って、GitHub のページを読んでいると、フランス人の同僚 Williams がやってきて、何読んでるの?というので、それを見せてあげた。
彼は GitHub のディスクリプションだけよんで、「あーこれはこうこういうことが出来るライブラリできっとこんなコンセプトだよ!」みたいなことを言い出した。彼ももちろんそのドキュメントは初めて見るのになんだろうこの理解力の差は。
自分だと、ドキュメントを読んで、チュートリアルをやってみて、コードを書いて試してみてやっと大体どんなものかが理解できるというのに。しかも、これは、彼だけではない。私だけ劣っている感じ。
同僚のJavaの世界で著名な寺田さんも言っていたが、これはものすごい差だ。彼らは我々ほどまじめじゃないので、少なくとも私と寺田さんは、この溝を、努力の量で埋めている。
だけど彼らはもっと楽にそれを成し遂げる。アジア圏の人は同僚にいないのでわからないけど、このあたりは日本人は不利に感じる。
技術力の差は英語力の差
この差がある理由は漠然と「英語力の差」ではないかと思っていた。寺田さんも同じように感じているようだ。
彼らは同じドキュメントを読んでも読み取れる内容が我々とは違っていて、同じ文章を読んでも、明確にそれが何を意図しているかイメージできるのだろう。しかし、これはどうやったら身に着けることができるのだろうか?
英語の勉強して、Proficient とかになったり、海外に長年住んで多読とかをすればいいのだろうか?多分それでもいいのだろうけど時間がかかりすぎる気がする。どうしたらいいのだろう。
Deliberate Practice
私は要領が悪いので、自分の生産性を高めてくれるメソッドを学ぶのが好きなのだが、この前 Deliberate Practice というコンセプトを知った。
何かをできるようになるためのメソッドなのだが、最初は凄くゆっくりから、1つのことに集中して練習するらしい。それを試してみようと思って、自分が知らなかった DependencyInjection のライブラリのドキュメントをその方式で読んでみることにした。
実施したことは下記のこと。
- ドキュメントを読むときに、わからないと立ち止まって意味を調べる、ゆっくり考える
- コードを読むときも、わからないときは立ち止まって意味を調べる、ゆっくり考える
ただこれだけ、先に先に行かず、本来なら17分で読める技術ドキュメントを精読してみた。すると、あることに気づいた。
自分は「コード」の意味がよくわかっていないのではないか?
これは、そのコードが「どのように動作するか?」をわかっていないという意味ではない。コードに書かれている英単語の意味が「ふわっと」しか分かっていないのでは?ということに気が付いた。例えば、コードを書いているときによく出てくる「Context」という用語がある。ここでは、「DBContext」が出てきた。ふわっとはわかるし、コードによくでて きて、大体どんな雰囲気のコードがでてくるかもふわっとわかる。問題は「ふわっと」しかわかってないことじゃないか?と思って、英英辞典を引いてみた。
The context of an idea or event is the general situation that relates to it, and which helps it to be understand. We are doing this work in the context of reforms in the economic, social and cultural spheres.
適当に訳してみると、コンテキストというのは、アイデアとか、イベント、それがかかわっていることの一般的な状況で、それが理解されるのを助けてくれるもの。例文としては、私たちはこの仕事を経済、社会、文化的な領域をリフォームするという文脈で実施している。
とある。HttpContext とかよく出てくるけど、HttpのRequest/Response とかにかかわかるデータやステートがごそっとそこに入っているけど、これは、この意味と照らし合わせると、明確にわかりやすいネーミングだなあとわかる。このContext の意味をもとから知っている人なら、あまりその内容がわからなくても、Context という単語の意味合いから、そのクラスがどういう責務を持っているかが容易に理解できそうだ。
英単語の意味を調べるのは英英辞書がお勧め
ちなみに、私は英単語の意味を調べるときは、英英辞書を使っている。なんかハードル高そうだが、英英辞書にもネイティブじゃなくて、第二言語学習者向けの説明が簡単になっているものがあるのでそれを使っている。なぜかというと日本語に翻訳した翻訳は意味がちがっていたり、元の意味が取りにくくなっているのがおおいからだ。私は iPhone のアプリを使っている。
他にも私がその文書を読むときに調べたよくあるけど、よく意味がわかってなかったものに、Transient がある。和英の意味を引くと意味が分からない。Transient は遷移的とかいてある。なんじゃそりゃ?英英辞書で調べてみると
Transient is used to describe a situation that lasts only a short time or is constantly changing. ...the transient nature of high fashion
Transient は、短い時間で、変わり続けるような状況。なるほど。強引に日本語にすると遷移的というのはまちがってはいないけど、こっちのほうがわかりやすい。で、例えば、これが、どういう文脈でコードで使われていたかというと、DI のコードがあって、DI の対象になるクラスを登録する過程で次のようなコードが出てくる。
service.AddTransient<ITransientService, TransientService>(); service.AddSingleton<ISingletonService, SingletonService>(); service.AddScoped<IScopedService, ScopedServcie>();
ちなみに、ここでは、シングルトンはこのインスタンスが呼び出されるときに、インスタンスは常に1つ、Scopedは、リクエストが同じなら同じインスタンス、Transient は、呼び出されるたびに新しいインスタンスが作られる。これだと、Transient の意味は上記とマッチしていない気がするが Guid を DI 対象のクラスで生成して、同じインスタンスが使われているかを調べるとどうだろう。Singleton は常に同じ Guidになるし、Scopoed はリクエスト内なら同じ、そして、Transient は、呼び出されるたびに、毎回「違うGuid」になる。つまり、毎回違うインスタンスになる。
短い時間で移り変わるというイメージを持ったTransientの意味と照らし合わせるとこれまたむっちゃわかりやすいネーミングだ。
他の例としても Container とかある。私だと、ふわっと、Docker のコンテナとか、コードの文章でも、コンテナって出てくる。技術やコードから逆算すると、船に積むコンテナみたいなイメージだろうか?と思っていたけど、最初の意味はこれだった。
A container is something such as a box or bottle that is used to hold or store things in ...the plastic containers in which fish are stored and sold.
もちろん、私が思った船に積むコンテナの意味もあるのだが、最初の意味を調べると、もっと一般的に何かをいれる箱みたいなものみたい。Docker のコンテナのイメージは船のコンテナのイメージが強いけど、コードだともっとカジュアルな状況につかわれている場合も多い。なんかの入れ物ぐらいな感じなのね。他にもこのコードの中では Service とか Registry とか、Populate とか Construct の意味を調べた。どれもこれも、頻繁にコードにでてくるのに「ふわっ」としかわかっていなかった単語の数々だ。
メタファーの意味を20年近くかかってやっと理解する
このように、コードがどのように動作するか?だけではなく、コードで使われている単語を英英辞書で調べることで、相当コードでなぜその英単語がチョイスされているのかが明確にイメージできるようになった。多分これはすっごい重要な事だ、なんで今までやってこなかったんだろう!と思ったが、そんなことはとっくに先人わかってたことで、しかも私もその概念を何年も前に学んでいる。
それは「メタファー」だ。2000年頃に Extreme Programming に出会ったときに、そのプラクティスの一つとして「メタファー」というのがあって、「クラスの名づけをするときに、比喩を使う。そうすると、ほかの人とその意味合いを共有しやすくなる。」とか書いてあった。
当時は正直意味もわからなかったし、「そんなん英語圏の人だけ有効なんちゃうかな」と思ってたけど、たぶんこれのことだ。だから、英語が一番できるアメリカの人のコードはきれいなことが多いのか!だから、ネイティブのアメリカ人やイギリス人じゃなくても、単語の意味を分かっている人はいろんな理解が早いのかとかなりの腹落ちをした。
メタファーってこれやったんか。20年近くたってやっとわかったわ。
最初からスピードアップできないだろうけど、ゆっくりはじめて、手抜きをせずやってるとだんだん早くなってくるんじゃないかと思う。
使われるメタファーの用語を理解しよう
というわけで、今回学んだことは、コードに出てくる単語はそんなに多くないので、自分がふわっとしか理解できていない用語が出てきたら、それを英英辞書で調べるとかなりすっきりするということだ。ツールの名前とかも調べるとよさそう。例えば Heptio という製品群に Ark というk8sのバックアップツールがあるのだけど意味を調べると
In the Bible, the ark was a large boat which Noah build in order to save his family and two of every kind of animal from the Flood
これは確かにわかりやすいわww
英語学習をがっつりやるより楽
となる感じ。ちょっとしたことだけど、英語全体をがっつり勉強してもこれらのボキャブラリに到達しないかもしれないので、コードに出てくる順から調べたほうが効率がよさそう。CLI のコマンドのサブコマンドとか普段使っている Build とか、Compileとかの意味を調べてみてもいろいろイメージできて楽しい。プログラミングの生産性向上目的なら、英語自体をふわっと向上させようと思うより圧倒的に調べないといけないことが少ないし、ふわっとしか意味がわかっていなくてもなじみはあるので、記憶に残りやすい。
しばらくいろいろ調べるのを楽しんでみて生産性が上がるか試してみたい。
今回は「メタファー」を理解できるといろいろはかどりそうだと気づいたので、ブログでシェアしてみました。