1年ほど前に話題となったプログラミング適性についてのエントリの元ネタとなった論文及びその他資料の解読を細々と始めた。英語が苦手な私にとっては文字通り解読だ。
夏休み中も進める予定だったのだが、他に色々と用事があって何も進められなかった。
論文2つは(私の主観では)長すぎる英文なので、それ以外の資料に手をつけている。内容は……今の時点では先のエントリから想像したものと大体同じなように感じている。
あの方法では、プログラミングというか計算機科学というか、とにかくこの道における壁として、
- 代入と系列
- 再帰/繰り返し
- 同時並列性
の3つがあると仮定している。その上で、一番最初の壁である「代入と系列」を題材として、しかし「代入と系列」とは違うポイントを計測しているように見える。
それは恐らく、
- 目にしたことがある記号に対して、既知のルールではなく「誰が作ったか分からない妙ちきりんなルール」を適用する、という発想に至ることができるか否か?
- その記号対して「ああすればこうなってそうなる」という作用についてのモデル/イメージを構築する能力があるか?
- 上記のモデル/イメージに従って、既存の「記号の羅列」を解釈していくことが可能か?
という点だと思われる……が、まだ資料に手をつけ始めたばかりなので、間違っているかもしれない*1。
とりあえず、このエントリでは上記の3点が間違っていないと仮定して徒然と書いてみる。
目にしたことがある記号に対して、既知のルールではなく「誰が作ったか分からない妙ちきりんなルール」を適用する、ということ
あのテストと似たような内容を即興でこしらえて、プログラミングとは縁のない人に見せたことがあるのだが、その人は非常に困惑したようだった。
どう困惑したかというと、「=」を等号という意味で理解しようとした為に、
int a = 10; int b = 20; a = b;
この3行目で躓いてしまった。「aとbが等号で結びつくはずがないっ」という訳だ。
「ふてくされて回答を空白のままに」した「学生」の中には、同じような発想をしたが為に混乱してしまった人もいるだろう。
この点については、プログラマである自分自身にとっても──身に覚えはないのだが──身につまされる所がある。要するに頭がかたい・発想に柔軟性がないということだ。
もっともこれに関しては、
- 「=」に関する新たなルールを学習する。
- 新しいルールに従って解釈を試みる。
という段階を経ることで解決できる可能性がある。というか解決できなかったら、今頃私はプログラマ以外の職業についていたことだろう。
プログラミングという行為には記号処理的な側面がある。プログラムを書く時は「誰が作ったか分からない妙ちきりんなルール」に従って記号を並び立てるし、プログラムを読み解く際には(ミクロな領域では)その「妙なルール」に基づいて挙動を解析する。
(代入の意味はさておいて)「=」を等号ではなく代入だと解釈すること──普段目にする記号を既存のルールとはまったく異なるものであると認識し、新たなルールに基づいて解釈すること。そのことに疑問を感じずに実行できるか否か。
COBOLなんかは事情が異なるかもしれないが、FortranやLispやC言語といった「英文とはかけ離れた」文法のプログラミング言語を使う場合には、そういった能力というか何かは必要となってくる気がしないでもない。
ある記号に対して「ああすればこうなってそうなる」という作用についてのモデル/イメージを構築することと、そのモデル/イメージに従って「記号の羅列」を解釈していくこと
記号処理的な視点でプログラミングを捉えると、
- ある記号に対して「ああすればこうなってそうなる」という作用についてのモデル/イメージを構築すること
- そのモデル/イメージに従って「記号の羅列」を解釈していくこと
の2つの記述は非常に自明なように思えるのだが、ここではもう少し深入りしてみる。
具体的にはこんな方向の横斜めぐらいな感じで深入りする。
これはC言語なんて使っているが為の弊害も含まれるかもしれないが、プログラムを読み書きする時、特にソースの字面からは分かりにくい部分(例えば副作用を発生させる演算子だとか、繰り返しの制御構文など)の作用なり動作なりを頭の中でイメージすることがある。
例えば代入というか、変数と代入を一緒くたにしての話だが、
a = 10; b = 20; a = b;
このコードを見て、例えばC言語とRuby*2とで両者とも似たような作用のイメージを持つ人もいれは、両者で異なるイメージを持つ人もいる。
私は後者だ。C言語とRubyとでは異なるイメージを持っている。
C言語での変数のモデルといえば、いわゆる「箱モデル」が有名だ。メモリという箱があり、その中に値を格納する。私自身のC言語の変数に対するイメージも、まあ似たようなものだ。
C言語の代入のモデルに関しては、有名なモデルは思い浮かばないのだが、私個人のイメージで言えば「バイト列のコピー」だ。コピー元は定数や変数で、代入することでコピー元の値がバイトレベルで別のメモリ領域にコピーされる。コピー元は消去されない。
ではRubyの場合はどうか? Rubyの変数に対する私のイメージは「C言語よりも安全なポインタのような何か」だ。変数は指定したオブジェクトを指し示す何かだ。
Rubyの代入に対するイメージはC言語のそれと似たようなものだ。但しコピーされるのはオブジェクトを指し示す為の何かだし、「C言語の素朴なポインタとは異なり、多分参照カウンタなり何なりの仕組みが背後にあるのだろう」ぐらいは念頭にある。
どうして私はC言語とRubyとで変数と代入のイメージが異なるのか? 具体的にはここでは書かないが、まあ「C言語の変数と代入のイメージをRubyの世界に持ち込んでしまい、大失敗した」という経験を経ているのは確かだ*3。
話を戻そう。
変数と代入といった初歩的なものに対しても、私は「ああすればこうなってそうなる」という動作のイメージを持っていて、ソースコードを読み書きする際はその動作イメージに基づいて色々と判断している*4。
先ほど「『=』を等号と判断してしまい」云々と書いた所で、解決策として、
- 「=」に関する新たなルールを学習する。
- 新しいルールに従って解釈を試みる。
を挙げたのだが、このルールの学習というのがつまり「『=』という記号に関して『ああすればこうなってそうなる』という動作のイメージを持つ」ということではないか?
もしそうだとすると、頭が固くなるほどルールの習得は難しくなることになるのではないか? 固定観念の壁みたいなものである。また複数のプログラミング言語を扱う場合、ある記号に対して言語によって異なる動作イメージを持ち、切り替えることになるのだが、それを実現するにはある程度の柔軟性が必要となるはずだ。
そもそも「ルールの習得」自体も敷居が高いものになるのではないか? なぜならそのルールは「誰が作ったか分からない妙ちきりんなルール」なのだ。そのルールに極力疑問を感じず、「あれはとにかくこういうものなのだ」と淡々と理解していくことは、私には誰でもできることだとは思えない。
プログラミングの適性を、別の何かで穴埋めする
さて、私にプログラミング適性があるかどうか考えたとき、実のところそれほど適性はないだろうと思う。
正直な話、プログラミング未経験の時に、
int a = 10; int b = 20; a = b;
こんな内容の問題が出されたとしたら、途中で混乱してしまっていただろうと容易に想像できる。
しかしそれでも、何とかプログラマとして働けている。この食い違いはどこからきているのだろうか?
私は「ルールの習得」が他人よりも遅いという自覚がある。プログラミングを始めた年齢が若干遅めであることも影響しているだろうし、何より性格的にムラがあり、興味のないことや苦手意識のあるものに対して学習意欲が全く沸かないという致命的な欠点がある。努力も嫌いだ。
その反面、興味のあることには集中できる。そして興味のあるプログラムを作るときに必要な「ルール」を学ぶのは苦にならない。また幸いな事に「ルール」自体にも少々興味がある。
あと一度理解できなくても、暫く寝かしておくことで何時の間にか何となく理解できるようになることも、最近覚えた。
とすると、(全く適性がないのはNGだろうが)多少適性に欠けていても、興味があって継続的に学習していればある程度はカバーできるのだろう。時間は掛かっても「『ああすればこうなってそうなる』という動作のイメージを持つ」という状態に至ることができる余地がある。
なお、あえて「努力」とは書かない。私は興味があったから耐えられたようなものだ。しかし興味を感じない人にとっては苦痛でしかない。いくら努力しても、苦痛なことを上達できるとは到底思えない。
結局、欠けている適性を埋めるのは「興味と学習と時間」ということになるのだが……「興味」を持つか否かということ自体が、ある種の適性を要求しているような気がしないでもない。