島までは遠い

佐藤正志@サークルアラウンドのことが少しわかる場所。プログラマーを育てるトレーナーとして、現役のソフトウェア技術者として、経営者の端くれとして、想うことをつづる予定。しばらくは工事中。

何度も書き写すことに意味があるのか。もしくは理解の為に必要な要素について。

f:id:ms2sato:20180217003025j:plain

はじめに

こちらへのアンサー。なんだか長くなってしまう感じだったのでTwitterでは難しそうと考えて、一旦場所を変えさせてもらいました。ちなみに、この一言で私は色々な想いを巡らすことができたので、とても有難い言葉であったと先に感謝をさせてください。興味深い問いをありがとうございました。

この文脈において「理解する」とはどういうことか

まず前提として、私はプログラミングを学ぶ時に「理解する」というアプローチを重んじています。そうするとまず私の思う「理解」についてお伝えするのが最初に必要だと思いました。改めて考えた時、以下の二つの組み合わせではないかと今は結論しました。

  • 組み立てられた論理を脳に写像できている
  • 概念を合点している

特にプログラミング言語やフレームワークは人が作った道具なので、作者の思う「論理を表現しやすい構造」を持っていると考えています。つまり、少なくとも作者がある時点で考えた一定の整合性の下に成り立っているはずです(もちろん破綻している何かもあるのでしょうが、今は目をつぶってください)。

私たちが学ぶ時にすることは、この彼らが出力した論理構造を逆に入力しているのだと思えます。その結果「この道具はxxxの為に使う道具だ」とか「xxxという複雑なものを意識しない為に隠しているのだ」などと整理する事になります。逆に考えると、整理した結果は作者がそれを作成した動機に近いものとなるはずです。

「理解する」とはこの「作者が表現しようとしていた概念や、課題解決の動機や仕組みを脳に写像する」ことではないかと思われます。

無心に書き写す事によって論理を写像できるのか

私の答えは「ごく一部の人にとってはYES。その他多くの人にとってはNO」ではなかろうかと推察しています。これは統計を取ったわけではないですが、私が出会ったプログラマーの卵や、現場のプログラマーを見ていて感じた事です。

「何度も書き写す事で共通した部分に気づく」という事自体はパターンマッチングして一致している部分を感じ取る事と考えて良いと思いますが、それは上記のような「作者の意図を脳に写像する事にはならない」と、私の頭では整理されています。パターンマッチングでは浅いという表現でも通じる人がいるかもしれません。

物事の考え方に、演繹法・帰納法のようなものがありますが、理解する時に必要なのは演繹法の脳であり、帰納法の脳では無さそうだと感じています。繰り返しの果てに何かに気づく時でも、どこかで立ち止まって演繹して理解に至っているのではないでしょうか。

繰り返しで帰納的に獲得している場合の例

私の会社のトレーニングでこのことに近い例が過去にあったのでちょっと出してみます。最近ではRubyやRailsの基礎を学ぶ時に、まず動画教材( 無料版がCodingCastで見れます。解説の動画を全部カットしたので、ScreenCastを真似するものです。 )を提供して予習してもらうことが多くなってきました。この動画を本格的なトレーニングの前に提供したりすると、何パターンかのアプローチをしてくださいますが「時間のある時に何度も繰り返し見る」という形で行ってくださる方が一定数います。

そして、実際にトレーニングに入る際には何かを作ってもらうという事になります。通り一遍の仕様だとパターンマッチングの脳でクリアしてくれます(かなり優秀な場合も多いです。記憶力で素早く書けるんですね)。

少しずつ意地悪な*1実装をお願いすると「システムの中で何と何が繋がっているか」が問われ始めます。例えば、あるところのメソッド名や変数名をあえて変えてもらうようにお願いしたりもします。途端にエラーが出て、それがスッと解消できるかどうかというところ一つでも、理解の深さがわかります。ただ、エラーメッセージの読みが鋭い場合もあるし、概念理解で「あっちを変えるの忘れた」と気づく場合もあるので、その動機が行動からわからない場合もありますけれども。 パターンで脳に入ってしまっている人は、そういう時のエラー解消に大変時間がかかります。一箇所変えた時に、何が影響を受けるのかが整理できていないのですね。論理構造の写像がまだできていない為だと私は考えています。

パターン化されているタイプの人は多くの場合、こういうエラー対応に弱いようです。トレーニングではパターンでインプットされてしまったものを、エラー対応や実装を通じて論理構造を考えていただき、確からしい理解に辿り着いてもらおうとします。

では正しい理解をなるべく早く獲得するには

これを考えるには改めて先の列挙に戻ります。

  • 組み立てられた論理を脳に写像できている
  • 概念を合点している

前者について。コードの繋がりを理解することをしていくことですね。全てのステップを一行1行追わなくても、例えば

  1. 受け取った通信の内容はroutesに渡されてControllerとActionが判断される
  2. 判断されたControllerのActionがコールされる。
  3. 何も指定しなければaction名に対応したViewがレンダリングに使われる

というような、コードの呼ばれていく大まかな繋がりがわかるだけでもかなりのことに対応できます。

実は後者はとても難しい場合が多いです。それは使い方だけを見たとしても「それがどんな概念なのか」を昇華するにはかなりの経験や苦労を要する場合が多いからです。私自身も概念レベルまで何でもかんでも消化できているのかと問われたらNOと言わざるを得ません。ただ、この部分はたくさんの経験を要すると割り切って、既に獲得している他者からインストールされるのも近道だと思っています。実はこの辺りが先輩に教わることの価値だと思いますし、経験値を継承して大きく加速できるポイントの一つであると思います。例えばMVCという概念を考えた時、下記のようなポイントがあると思いますが、最初からこれに合点した人は物凄くセンスがあるのではないでしょうか。そして、これらはより良いコードを書くには大事ですが、そうでないならMUSTではありません。前者の時点できっと動くコードは書けているはずだからです。

  • Viewという表示を司る部分の変更が、大切なロジックの根幹であるModelへ影響する事をできるだけ防いでいる。
  • Controller/View はWEBの事を知っている層であるが、Modelはそれに依存しない。これによってModelだけをWEBのシステムではない部分でも呼び出したりすることが容易になる。

これくらいが良いのでは?

  • 一回真似してみて動くものを手に入れる。
  • 真似した内容をうまくアレンジしながら今度は自分のものを作る or 上記で出来上がったものを改造しながら理解を深める。
  • 難しいことがあったら文書のコンテンツを読んでみたり、最初に動かせたサンプルを弄ったりして確認する。
  • もしも自分でどんどん作れそうだと思ったら、立ち止まらずに進む。
    • コースに乗る必要はなくて、あとで分岐点に戻っても良いじゃないですか。ワクワクしてる時にガンガンやりましょうよ。
  • 次の壁に当たるので教材でも書籍でも人でも何かに当たって新しい情報を得る。
  • 上記を繰り返す。

真似を繰り返すのが回数という数字になって達成感を得てしまうのはソシャゲで何回もタップすると何か出てくるとか、レベルが上がるようなのと似ている感覚ではないでしょうか。本質的に得るべきものは得られてないかもしれない、と疑った方が良いです。

おしまいに

関連してすごく長く続くので一回バッサリカットしました。終わらん笑

既にかなり長くなったのでこのあたりでキーボードを打つのをやめますが、私が考えている「無心に繰り返すことにはあまり意味がない」ということの根拠とか考えをもう少し丁寧に表現してみました。

ちなみに、ツイートの方でも書いていますが、実は繰り返しが本当に必要な人が一定数存在するんですね。このケースはおそらく明文化することができないだけで、何かの形で感じ取ってやれている気がします。繰り返すことでパターンマッチングではないそれが作られるイメージ。私はこのタイプの人を理解してあげることがとても苦手だったりしています。まだまだ修行が足りませんね。

*1:とは言え実際によくありがちな事をやるわけですが