学習

頭の中の灰色の細胞が CPU や HDD だったとする。
知っていることが増えるのは HDD に書き込んだからということにしよう。
しかし、プログラミング能力が向上することを説明するのは難しい。
なぜなら CPU は変わっていないのだから。


考えられるのは HDD の中から似ているコードを検索することだ。
HDD に貯め込んだコードの量が増えるほどプログラミングできる範囲は広がる。
しかし、コードの量が増えるほどプログラミング速度が遅くなってしまいそうだ。
これは観測結果と一致しない。
むしろ広範囲の知識を持っている人の方がプログラミングも速い気がする。
CPU も HDD も優秀な人がいることはわかるが、自分自身でも知識が広がった方が速くなってるのでハード的な問題ではなさそうだ。

認知心理学の知恵を借りる

岡本浩一氏の 『上達の法則』 を読んだところ、知識は 「宣言型知識」 と 「手続き型知識」 の2種類に分けられるらしい。

  • 宣言型知識は、円周率は 3.14 のような一般的に 「知識」 と呼ばれるもの
  • 手続き型知識は、言葉では言い表せない 「手続き」 を含んだもの

技能の習得にはこの両方が必要で、これらを効率よく記憶、検索、利用できるようになることが上達を意味する。


では初心者と上級者の違いは何なのか?
まず脳には制約があって、脳に存在するワーキングメモリは7個ぐらいの塊で出し入れしなければならない。
上級者は知識を塊に変換する方法の種類が豊富で、かつ塊を小さくできたり大きくできたりするので初心者より出し入れしやすい。
初心者はワーキングメモリのフィルタではじかれるものがあるから同じ技能経験で得られるものも変わってくる。


ここまでが書籍の2章に書かれていた内容

どれくらい違うのだろうか?

塊の認識の違いは、カスパロフ氏の 『決定力を鍛える』 に書かれていた。
人間が計算力でコンピュータに対抗できるのは、意味のある単位にまとめて組合せの数を減らせるからだそうだ。
うまく塊を扱えれば線形的な違いではなくオーダーの違いを得られる。


しかしチェスは何手読めるかで勝敗が決まるわけではないそうだ。
同じ局面を見て黒が有利という人と白が有利という人に分かれる。
計算力と判断力は別の軸らしい。
「計算力の優劣で判断する人を決める」ことは「定規を持っているから長さで決める」ことと似ている。*1


プログラミング自体は大抵答えのある問題を扱っている(実装したい機能や計算したい値がある)はず。
そうするとやはり塊を扱う能力が重要となってくる。
ウサイン・ボルト選手は平均より2倍速いわけではないが1番速い。プログラミング速さは実際どれぐらいなのだろうか?
これは難しい問題らしい。

しかし、アルゴリズムのオーダーと同じように考えるとやはりうまく塊を扱えることがポイントになりそうだ。
塊を扱う単位を変えたところでオーダーが変えられるわけではないが、扱う単位を変えられなければばオーダーは変わらない。

知識の塊の扱い方

これを知りたい。
上級者から教わることがある。
「そこはこの2つセットで考える」 とか 「こっちから見る方法もある」 みたいに。
そうでない場合は、上級者の切り口をみて自分で考えるしかない。
「塊を小さく切り分けているな」 ということは分かっても、どうしてその単位なのかは分からなかったりする。
オーダーの違いや手続き型知識の場合もあるので必ずしも聞いて分かるとは限らない。


世の中には斬鉄剣の使い手のように知識の塊を 「また、つまらぬ物を斬ってしまった」 と簡単に扱える人がいる。
そのような人は大抵のことが遅延学習法で間に合う。一方、斬鉄剣を持っていない人はどういう順序で学ぶべきか?
持っている人より、どうすればオーダーが変わるのか、今のオーダーで十分なものは何かということを意識して選択した方がいいのだろう。
見積もれるわけではないので意識するより具体的な方法を思いつかない。


「なぜ関数プログラミングを学ぶのか?」 という質問に対する個人的な答えは、「知らない切り口があるから」 だ。
もちろん関数プログラミング以外ににも新しい切り口は存在するのでそっちを優先するという選択も考えられる。
必ずしも使うから学ぶわけではないし、今後流行しそうだからでもない。
「現在知っている言語で実装できているのになぜ?」 と考える人は、現在のオーダーで今後も間に合うのか考える必要があるはずだ。


今は、『すごい Haskell たのしく学ぼう!』 を読んでいる。
本になっているのだから宣言型知識として書かれている。
しかし、技術として両輪となる手続き型知識を私はまだ得られていない。
得られていない言い訳を考えてたらこんなことになってしまった。
『初めての人のための LISP』 を読んだときも再帰で考えることに苦労した。
そのときはここを参考にしながら読んでいって何とか14章まで読んだ。

その経験があるので、今回も最終的に理解できるだろうぐらいの感覚で読んでいる。
とりあえず、手続き型知識を得られるように訓練しなければならない。

追記

数学ガール ガロア理論』を読み始めた。

「なるほど!確かに対称式が係数で表せています」テトラちゃんは式を確認して言った。「対称式はいつでもこのように係数で表せるんですね……ところで、こういう変形って、なるほど!って思うんですが、自分では思いつきそうにありません。どうしたらできるようになるんでしょう」
「練習」とミルカさんが即答する。
「そうですか……」とテトラちゃんが言った。

テトラさんはどういう風に練習をすればいいかを聞いているような気がするのだが…
しかし、テトラさんといえば総当りなのだから表を作っておけばよいと思った。
ミルカさんが使ったことがあるテクニックを一覧表にしておいて毎回検索。


知識の塊も多次元テーブルでモデリングしておけばよいだけなのか?
未知の列が追加される場合は仕方がないが、追加されたときに他の軸との交点がどうなるのかを埋める。
そういえば『なぜ関数プログラミングは重要か』でも“新しいデータ型を定義したときにその型を処理する高階関数を書くべきである”と書かれていた。

2012-06-04 追記

発想法とか

コーディングに置き換えたらどうなるのだろう?


プログラム版 20Q が欲しい。
データはたくさんですか?データにランダムアクセスできますか?とか答えているとプログラムが返ってくる。
そう考えるとタグが重要で、勉強の質と量の質はそのためのタグが足りているかどうかだと思った。
子曰く 「勉強したら検索のこと考えてタグ付けなきゃだめだよ。タグを付けていても量がなきゃだめだよ。」
でも違和感ない。


手続き型知識を得られないのは、宣言型知識に十分なタグを付けてないので、他の知識との連動できない状態なんだと思う。
ファンクターを、どうタグ付けしたらいいのかよく分からないから、どう使うのか分からない。
タグ付けできれば今まで同じタグを使っている箇所をファンクターで置き換えることができる。
ただ、分からない理由が分かっても分かったことにはならない。

*1:当然計算力で解決する問題は違う