技術者ブログ

クラウド型WAF「Scutum(スキュータム)」の開発者/エンジニアによるブログです。
金床“Kanatoko”をはじめとする株式会社ビットフォレストの技術チームが、“WAFを支える技術”をテーマに幅広く、不定期に更新中!

2017年10月

1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
  • お問い合わせはこちら
Scutum開発者/エンジニアによる技術ブログ WAF Tech Blog

わざとゾーンに入らずにコードを書く

はじめに

「ゾーン」あるいは「フロー状態」と呼ばれる精神状態があります。スポーツや楽器の演奏、ゲームのプレイ中、そしてプログラミングなどにおいて、高い生産性や成果をもたらすことがよく知られています。プログラマーであれば、誰でもコードを書いているうちに、いつのまにかゾーンに入っていたという経験があるのではないでしょうか。

高い生産性や、そのこと自体が気持ちの良い体験であることから、基本的にプログラマーがゾーンに入っていることに対しては肯定的なイメージがあるかと思います。しかし今回は、筆者の個人的な経験に基づいた「わざとゾーンに入らずにコードを書く」というメソッドについて紹介したいと思います。

ゾーンとプログラミングへの一般的な見方

ゾーンに入っている間、プログラマは非常に生産的になり、コードを書くということ自体が楽しくなってきます。自身が書いているコードの内容に対する迷いがなく、目的の機能を実装するというゴールに向けて最短距離を突き進むイメージです。気がつくとあっという間に時間が経過しており、禅にも通じるような特殊で非日常的な快感を味わうことができます。

ゾーンは突然の電話による呼び出しなどによって簡単に壊れてしまうことがよく知られています。そのため、「プログラマーにはできるだけ電話しない」「話しかけるタイミングに注意する」など、意識してプログラマをゾーン状態から引きはがさないよう注意されている管理職の方などもいらっしゃることでしょう。

プログラマにとって働きやすいと言われている会社のひとつであるGitHubでは、各自がゾーンに入ってコードを書くことを強く意識しているようです。How GitHub Worksの中には、「The best solutions happen when you're in the zone」と書かれているスライドがあります。

では、なぜ筆者はわざわざ「ゾーンに入らないでコードを書く」ことを考えているのでしょうか。

ゾーンに入ることは難しいことではない

ゾーンに入ること自体はそれほど難しいことではありません。よく「一流のアスリートや演奏家がゾーンに入り...」のように紹介されがちですが、小学生がゼビウスのようなシューティングゲームをやるときにも簡単にゾーンに入りますし、初心者プログラマが中級者になるくらいのレベルでもゾーンに入ることはまったく珍しくありません。

特にプログラミングは、プログラミング言語による開発のリズム(何が可能で何はできないか、どんなライブラリがあるか、どんな関数の呼び出し方か、といった一種のルールのようなもの)に慣れれば、タイピングとそれに対応する画面の描画というフィードバックがあることから、容易にゾーンに入ることができるものです。プログラミングは、例えば自身の活動に対するフィードバックがそれほど高くない読書や映画鑑賞といった体験に比べて、ずっとゾーンに入りやすいものだと言えるでしょう。

ゾーンに入る体験はそこそこ非日常的であり、またそのこと自体が気持ちがいいため、プログラマはゾーンに入ってコードを書く体験を特別視しがちな傾向があります。

プログラミングとゾーンに入る条件

ゾーンに入るにはいくつかのよく知られた条件があります。ここでプログラミングと特に関係してくるのは以下の条件です。

  • 明確な目的
  • 専念と集中、注意力の限定された分野への高度な集中
  • 直接的で即座な反応
  • 能力の水準と難易度とのバランス(活動が易しすぎず、難しすぎない)

コードを書いているときには通常はっきりとした目的(実装すべき機能など)が存在しており、1つめの条件をクリアします。また、活動として行うことができるのは、そのとき使っているプログラミング言語や実行するプラットフォームなどによって形成される情報空間に限定されます。これは2つめの条件をクリアさせます。また、先述したとおり、キーボードのタイピングに対するフィードバックがあるので、3つめの条件を満たします。

そして大事なのが4つめの条件です。活動が易しすぎず、難しすぎないことが必要です。この「易しい」「難しい」というのは、コードを書いているプログラマ本人のスキルが基準となります。そのため、ある問題が存在した場合に、中級プログラマはそれを「易しすぎず、難しすぎない」と捉え、ゾーンに入りながら解く可能性がある一方で、熟練プログラマは同じ問題を「易しすぎる」と捉え、ゾーンに入れずに(退屈して)解く可能性があるのです。

熟練プログラマを強引にゾーンに入れるには

さて、ここで仮に「プログラミングの際に、ゾーンに入ること自体が大事である」としてみます。熟練プログラマに、彼にとって易しい問題をゾーンに入って解かせるにはどうすればよいでしょうか。答えは「プログラミング言語や解き方を、いつもとは異なるものにする」ということになります。例えばJavaが得意な熟練プログラマに、「Javaは禁止、Clojureで解くように」と強制してみましょう。するとJavaでは易しかった問題の難易度が、いい感じに上がります。そのため一連の作業はチャレンジングになり、熟練プログラマは(Clojureでは中級レベルだとします)ゾーンに入りやすくなるでしょう。

また、別の答えとして「Javaを関数型言語のように使いなさい」とか、「いつものようなスレッドの使用は禁止。非同期APIのみ使って並行処理を実装しなさい」のように、Javaという言語は変えずにライブラリの使い方や開発手法、デザインパターンなどを禁止することにも同様の効果があるでしょう。

しかし、本来易しいはずの問題を、わざわざ難易度を上げて解く必要はあるでしょうか?ビジネス的な観点で言ってしまえばこれは間違いで、易しい問題は易しいものとしてきっちり片付ける(実装を終える)ことが望ましいでしょう。プログラマがゾーンに入って実装したか、それとも入らなかったかは、あまり重要ではない話です。

ある簡単な機能の実装を熟練プログラマに依頼したときに、「簡単すぎて退屈だったから、本来はあまり必要ないんだけど、前からちょっと興味があった○×というライブラリを使ってみたらなかなかいい感じ。HAHAHA」ということになったことはないでしょうか。そして数日後に「あのライブラリ、バグがあったみたい。ごめん...」みたいになったことはないでしょうか...。

プログラマにとって、実装する前から「これは簡単に片付けられるな」というような問題は、退屈でやりたくないものです。しかしビジネス的、プロダクトのクオリティ的には、退屈であっても、間違いが少ない、慣れている方法で取り組んだ方がよい場合が多いでしょう。

クリエイティブになりすぎる問題

ゾーンに入っている間は発想が非常にクリエイティブになります。がむしゃらにゴールへの最短距離を目指しやすい精神状態になるため、過程よりも、「結果に辿り着くこと」を重視したコードを書きがちになります。知っている限りの知識が総動員されてウルトラCのような妙技が浮かぶこともしばしばです。その結果として読みにくかったり、メンテナンスしにくかったりするコードになってしまう傾向があります。

最短距離を突っ走るためにリフレクションやevalのような黒魔術が非常に魅力的に見えます。非常に量の少ないコードや、あるいは短い時間で機能を実装することができる反面、翌日になりゾーンから出た状態で読み返してみると、何をやっているのかわからない(しかし一応動くようである)というようなコードになってしまうのです。特にRubyやJavaScriptのような自由度が高い言語ではこの傾向が顕著です。

安全側に倒しながらだとゾーンに入りにくい

バグが入らないように石橋を叩いて渡るようなコードを、当たり前の慣れた開発手法で書いていく場合には、ゾーンに入りにくい精神状態となります。というのは、自分が書いたコードを、書いた直後に疑う必要があるからです。「本当にこれがベストか?この関数はこっちのクラスに実装した方がよいかな?」のように自分のコードに疑いを持つような精神状態は、ゾーンに入る条件とも言える「自身の活動に自信を持った状態」と相反するため、あまりゾーンに入ることができません。「このコードが100%正しい!よし、この関数を実装したら次のクラスだ!」のように疑いを持たないイケイケなモードの方が、ゾーンに入りやすいと言えるでしょう。

テストをしっかり書いたり、プログラムの設計を慎重に見直しながらコードを書く場合には、「問題が解決できること」が早い段階で明らかになることが多くなります。この場合にも「解決できるな」とわかった時点で問題の難易度が下がるため、「活動が易しすぎず、難しすぎない」という条件から外れることから、ゾーンに入りにくくなります。ぎりぎり「解けるかどうかわからない」くらいの難易度が最後まで保たれていると、ゾーン状態を維持しやすくなります。

わざとゾーンに入らずにコードを書くというメソッド

このように、ゾーンとプログラミングには密接かつ複雑な関係があります。筆者は、自分がコードを書きながらゾーンに入ってしまっていると気がついたときには、「問題を難しく捉えすぎていないか」「慣れない不必要な開発手法を持ち込んで、楽しんで解こうとしていないか」と考える癖を付けています。もちろん問題が本当に難しいのであればゾーンに入ることには何の問題もありませんが、逆にそのような場合には「今の自分にとって、ゾーンに入ってしまうほど実装が難しい機能を、現段階でプロダクトとしてリリースしていいのか?」と考えるようにしています。

このようにプログラマの楽しみよりも、プロダクトのコードの安定性や読みやすさを重視するのが「わざとゾーンに入らずにコードを書くメソッド」の狙いです。

ゾーンとプログラマの成長

これまで、基本的にプロダクト側の安定性を基準にしてきました。しかし、プログラマのスキルに焦点を当てた場合には、ゾーンに入りながらのプログラミングは素晴らしいものだと言えます。取り組んでいる問題はちょうどよい難易度であり、間違いなくプログラマを成長させるでしょう。また、そのこと自体が気持ちの良い体験であり、充実した生活に結びつきます。仮に毎日ゾーンに入っているプログラマがいるならば、その人のスキルはぐんぐん伸びていっているはずです。

もし研究目的のコードなどを書いているのであれば、ゾーンに入っていることはよいことでしょう。自身が「乗り越えられるかどうか」という絶妙な難易度の問題にチャレンジしている証拠だからです。ただし、ゾーンに入れないほどの難しい問題にチャレンジすることも悪いことではありません。

筆者がゾーンを解禁する場面

筆者が自分自身に「ゾーンに入ること」を解禁する場面が2つあります。1つめは「ゴールに速く到達することが大事で、過程は汚かったり、再現性が低くてもよい場面」です。デバッグや障害対応、リバースエンジニアリングなどがこれに当たります。2つめは、単純に楽しんでコードを書いて良い場面で、趣味のツール作成や研究用のコード書きなどがこれに当たります。自分がどの程度の難易度の問題でゾーンに入るのかは非常に興味深いところです。

まとめ

今回はゾーンとプログラミングの関係について、筆者の個人的な意見を紹介してみました。フィードバック等あればお気軽に@kinyukaまでお寄せください。