逐次実行と再帰によるループの応用
話は再び逐次実行に戻る。きしだ氏によれば、逐次実行はプログラムカウンタの状態遷移だという。
逐次実行とは、プログラムが一つ一つの処理を順番に実行することであり、この過程でプログラムの状態が次々と変わっていく。つまり、プログラムカウンタが持っている『どの部分を実行しているか』という状態が変化していく(状態遷移する)わけだ。変数であれループであれ、この考え方がすべての基礎になっている。
これを理解せず、普通の文章を読むようにプログラムを読むと学習につまずいてしまう。それなのに誰も教えてくれないので、書いて慣れるしかないという状態になってしまっている。
最後にきしだ氏は、ループの応用として再帰についても言及した。再帰とは、処理の過程で自分自身を呼び出すことを指す。
たとえばサンプルコード[10]では、メイン処理の中でメイン処理が呼ばれている。これにより"hello"が無限に出力され続けることになるが、Javaの場合はStackOverflowErrorが出るため、実際には無限には動かない。ただし言語によっては、このような記述で無限に"hello"が出力されるものもある。
再帰を使用する際には、何らかの条件を入れて一定のタイミングでループを抜けるのが一般的だ(サンプルコード[11])。きしだ氏は「先に終了条件を書いて再帰を行わない値を返し、その後で再起する処理を書くというパターンを覚えておくと、プログラムを書きやすくなる」とアドバイスした。
またきしだ氏は、状態遷移が複雑になった入れ子状態の例も紹介した。サンプルコード[12]は、1対のカッコの対応を判定するサンプルコード[9]をさらに複雑化させ、中括弧、大括弧、マル括弧の3パターンのカッコで対応を判定するという例である。
「現在どの種類のカッコが始まったかを覚えておくためには、スタックが必要。スタックを自分で書くのは難しいが、再帰を使うと書きやすい。そもそも再帰はスタックを隠蔽しており、再帰のメソッドに与えるパラメータはずっとスタックに積まれていく。だからカッコが始まったら、そのカッコが始まったという情報を伝えつつ再帰を行えば、判定処理ができ上がる」
きしだ氏によれば、再帰を使うと入れ子のある正規表現に似た処理ができるという。これは、普通のプログラム言語のようにさまざまなカッコがあり、それが入れ子になっている状態のことだ。
このようにスタックと正規表現で表せるような言語を文脈自由言語という。ここでいう文脈自由とは、コンテキストフリーなのでどこから読み始めても同じように読み取れるという意味だ。今使われているプログラミング言語は、原則これがベースになっている。
最後のまとめとしてきしだ氏は、「ライブラリの使い方は、AIに聞けば教えてくれる時代。単純な知識の蓄積には意味がなくなるだろう。だからこそ、もっとちゃんとプログラムを書けて、読み取れるようになりましょうと言いたい。今日解説した逐次実行の概念は、その基礎となるものだ」として、セッションを締めくくった。