やりながらメモしたことをとりあえず並べておく。ちょいちょい手なおしが入ると思う。

SICP(Structure and Interpretation of Computer Programs)という技術書がある。 22歳くらいの時に名前を知って読みはじめた。その後何度かの中断をはさみ、色々と寄り道をしながら進めていき、昨年の11月くらいに最後まで到達した。 15年くらいかかったことになる。

本の内容自体は現在では無料で読める。いくつか日本語訳があるが、個人的にはこれが一番わかりやすかった。 hiroshi-manabe/sicp-pdf

あまり整理していないけど、自分が読んで写経したり、問題を解いた形跡はgithubリポジトリに置いてある。 後半になると問題の難易度が上がっていき、最後の問題(5.52)は半年かかった。本当に大変だったし、何度も諦めかけた。

SICPをやって得られたこと

「勉強とは何か?」について自分なりにわかってきた。 40手前にして今更感はすごい。ただ、プログラミングに限らない、今後普遍的に役に立つ能力だと思っている。

プログラミングに対する基本的な態度や考え方。OOPだとか関数型だとか、そういう時代によって変わっていくところではない、問題解決のための心構えのようなもの。 ここ、あまりうまく説明できない。説明できるようになりたい。

そのために必要なこと

問題を自力で解こうとする。これめちゃくちゃ大事。

日本語のSICPのサイトにはこんなことが書いてある。理由が書いてないので自分が理解したことが訳者の考えていることと同じかはわからないけど、ある程度今は納得している。

自力で解く(あるいは少なくともそのような努力をしてみる)ことで、自分の中に適切なメンタルモデルが構築できたか?の検証ができて、 これが自分にとっては必要な行為だった。 多くの技術書の類は、確固として存在しているはずの、著者のメンタルモデルをあまり説明しようとはしない。 そこが理解できていないと、内容を読み進めても頭に入ってこなくなってしまうので、かなり重要だと思っている。個別の内容以前にそこについて教えてほしい。まあ、そう簡単には説明できることではないのかもしれない。

SICPを単に「読んだ」だけだと、少なくとも問題を解けるようなメンタルモデルの構築に成功したかの検証ができない。 自分が問題を解くことで得られた考えかたは、著者のものとは異なるかもしれないが、少なくとも問題を解くことはできる、ある程度有効なものができているはずだ。

なんかそのあたりのことを考えていたときのtweet。

問題をとくためにやったこと

SICPの問題は、ものによってはかなり規模が大きいものがある。それを解くにあたっては、こんなことをやってみていた。

  • 「自分が解ける内容に問題を適切に分解できているか?」を検証していく。普遍的ではないが問題の一部分について答えられてるような、回答のプロトタイプを作ってみる。

  • 詰まった場合、なんらかの概念を誤解していることが多い。その先の章や節で説明されていることが含まれることもあった。これは初学者には判断できない。著者の気持ちになると、何かを完璧にボトムアップで説明するのはすごく大変で冗長になりそうなので、ある程度は仕方ない。この部分は、先人が身近にいたほうがよかった。

  • 本当にわからなくなった場合、紙にペンで図などにをあらわしてみると、見落としてることとか、誤解してることが分かりやすかった。

  • それでも本当にダメで、3日以上悩んだ場合は検索して答えを見ることもあった。ネット上にある回答は(自分のも含め)、本当に正解なのか時々疑問に思うようなものもあった。そのあたりは自分で納得できる回答であるか、内容を良く読んだほうがよい。

これはSICPに限ったことではなく、問題解決にあたっての普遍的な方法なのかもしれない。途中で読んだ「いかにして問題をとくか」が役に立った。

つまづきやすいポイント

動作検証ができない問題は、結果がわからないため結構辛い。その先で実装される何か(たとえばインタプリタとか)が実装済みであるという前提で、 問題が与えられたりすることがチョイチョイある。具体的には

  • 図形言語(これはracketでやるとよい)
  • 回路シミュレータ
  • evaluator
  • compiler
  • vm あたり。

その他の感想

  • 時間投資効率を重視するのであれば、「3章までを問題を解きつつ進める」というのが良いと思う。大抵の「プログラミング」はこの範囲で十分。
  • 4章から先は「深淵な何か」みたいなもので、直接役に立つことはあまりないのではと思った。VMをつくりたいとか、言語をつくりたい人には大事かもしれないが、それはもっとよい別の書籍がある気がした。
  • schemeは単純に見えるがその実中のほうは結構いろんなことしないといけない。環境とかクロージャとか。というのが実装してみてわかった。
  • replの力はすごい。try & errorがものすごい勢いでできる環境。これはハマる。