ちょっと前の話だけど,すこし時間ができたので.
3/25の,「みんなのデジタル教科書教育研究会」で,久野さんにビスケットを紹介していただいた.その中のスライドの一部分.
素朴な疑問:これ(ビスケット)がプログラミング言語と言えるのか?
YES.プログラミングの本質は「ある規則に従って自動実行」であり,ビスケットの「めがね」がやっていることはまさにそれ
この説明は,非常に正しい.しかし,僕はここでもう少しつっこんでこれを議論したい.
そもそも,コンピュータができることは何か.何はコンピュータは得意で,何は不得意か.
一言で言うと,コンピュータとは,「小さな変化を高速に自動的に実行する」というものである.
小さな変化とは何か.どのように実行するのか.この2つを考える.
小さな変化とは,分かりやすくはハードウェアが直接実現している演算である.あるレジスタやメモリなどの値で計算をして,その結果があるレジスタに書き込まれる.ハードウェア中のコンデンサにたまった電荷が増えるか減るか変化するということである.それらをもっと複雑に組み合わせたまとまりを一つの変化としてとらえる場合もある.一般的にプログラミング言語が高度になるに従って,小さな変化は大きなまとまりになってくる.
プログラミング言語の設計においては,小さな変化を何を何種類くらい選ぶのかが重要になる.重複した機能を異なる種類の変化として設計するのは,設計がへたくそである.
もう一つ,どのように実行するのかである.コンピュータのハードウェアはノイマン型という仕掛けが非常に効率がよく,性能・コスト的に成功したので,ノイマン型=コンピュータととらえられがちであるが,本当はいろんな種類のコンピュータがある.小さな変化を積み重ねるという点は,どの種類のコンピュータでも同じであるが,その変化をどのように実行するかが,異なっている.
ノイマン型のコンピュータでは,この小さな変化のことを命令と呼ぶ.命令を列にしてコンピュータに与えて,それを順番に実行して行く.たとえば,ここから東京駅まで行きたいとき,そこに行くための手順を命令にするのである.△駅まで歩いて,○線の◎方面へのり,×駅で乗り換え,...といった手順になろうか.
ところが,実際のコンピュータ(やロボット)はここまで賢くはない.一番最初の△駅まで歩いて,ということが命令としては大きすぎるのである.まずは外にでるためにドアを開けなければならない.ドアを開けるためにはドアノブを回さなければ開かない.靴もはくように命令しないと裸足で出て行ってしまう.そもそも歩くためには,右足と左足を交互に前に出すということを命令しなければならない.足を前に出すというのも,脳が勝手にいろんな筋肉を上手に制御しているからできるわけで,実際のロボットならこのモータをこれくらい回しつつ,別のモータをゆっくり回す,といったことをさせないと足が前にでない.
なのでノイマン型でコンピュータをちょっとでもまともに動かそうとするのは本当に気の遠くなる作業なのである.
このノイマン型コンピュータの最大の欠点は,突発的な事象に弱いということである.たとえば,うまく外にでて,道を歩けたとしても,とつぜん車が横切るかもしれない.そういうときは車に当たらないように歩くのを止めなければならない.赤信号も守らなければならない.
ノイマン型コンピュータには条件判定という特別な命令がある.状況がどうなっているかを調べてそれに従って動きを変えるのである.交差点に来たときに,赤信号かどうかを調べて,赤信号なら進まない,青信号なら進む,といった使い方をする.この条件判定の命令は,信号器のあるところすべてに置かなければならない.1丁目の交差点での条件判定,2丁目の交差点での条件判定.全部必要である.知らないうちに信号機が新設されたら,赤信号を調べずに交差点に入ってしまうだろう.ときどき,コンピュータがとんでもなく常識はずれのことをしでかして大きなニュースになってしまうことがある.この間違えの多くは,このような重要な条件判定を入れ忘れたことにある.
このように,慎重に命令の列を並べれば信号器に対しては何とか乗り切れるけれど,突然横切った車に対しては,そうはいかない.無理やりやるとするならば,足を一歩前に出す前に,かならず車が通らないかどうかを調べるというやりかたになるだろうか.ノイマン型のすばらしい特徴は本当に高速に命令の列を実行できることだから,こういう慎重すぎる条件判定をしてもそれほど影響はない,ともいえる.また,実際のコンピュータは,純粋なノイマン型ではなく,途中で命令の実行を割り込む仕掛けなど,沢山の仕掛けで解決している.とはいえ,ノイマン型の基本は普段と違うことが得意ではないということである.
そして,その後に発明されたノイマン型ではないコンピュータはそういった欠点を補うようなものだったり,いちいち信号器のある交差点のことを考えなくてもよいものだったりする.しかし,それらがノイマン型のコンピュータに勝つことは無かった.その理由はノイマン型コンピュータが圧倒的に安く高速に実行できるからであった.
で現在は,そのノイマン型のコンピュータの上で,理想的なコンピュータを動かす.コンピュータの上で別のコンピュータを動かすというのは,実に不思議なことではあるけれど,よく行われる手法である.普通は数倍~数万倍とコンピュータが遅くなるのであるが,ベースのコンピュータが圧倒的に速くなったので,そういうやり方が可能になった.
つまり,我々は理想的なコンピュータを考えることができるようになったということなのである.
ここで,スクラッチとビスケットの思想の違いがはっきりと見える.スクラッチは伝統的なコンピュータとはこういうものですよ,というのを教えるためのツールである.それに対してビスケットは理想的なコンピュータを考えてそれでコンピュータとは何かを教えるためのツールである.
コンピュータとは伝統的なノイマン型しか存在しないと考えている人にとってはビスケットはコンピュータではないと見えるかもしれない.しかし,最初に述べた「小さな変化を高速で実行する」という性質をビスケットはきちんともっている.むしろ,ビスケットの唯一の指令「メガネ」は,小さな変化をそのまま表現しており,メガネを組み合わせることは,本当に小さな変化を集めている感じがする.無駄な構成要素をとりさって,真にコンピュータの本質に迫っているとは言えないか.
メガネのもう一つの仕組みは,すべてのメガネには条件が入っていることである.ビスケットの実行は毎回メガネの条件を調べて,その条件をクリアしたメガネの中でもっともよい点数で条件をクリアしたものが,そのメガネが指示している変化をさせる.
このメガネの組み合わせ方は,人間がルールを覚えて行動することとよく似ている.ドアがあったらドアノブを回す.赤信号が見えたら止まる.車が横切ったら止まる.これらのルールは,どの順番でその条件が成立するというのは関係ない.どんなときでも,その条件が成立したら即実行するのである. 初期の人工知能プログラミングで,if-thenルールというのが使われたが,それと同じである.
しかし,これはこれで,コンピュータの非常識に起因するこっけいさが消えたわけではないるのであるが(たとえば窓の外の信号器を見てしまって動けなくなるとか),それでもノイマン型の融通の利かなさよりは楽になっている.
ビスケットでのプログラミングは,純粋に必要なことだけに集中できる.大きな変化を小さな変化に分割し,どういうときにその小さな変化が起きればよいかをメガネで作る.プログラミングを学ぶ上で重要なのは大きな変化を小さな変化に分割するという部分である.もしくはその逆,小さな変化を組み合わせて大きな変化のシステムを作ることでもある.
ところが,他のプログラミング言語では構成要素が多すぎて,小さな変化の組み合わせとしてとらえる,こと以外のことをいろいろと考えなければならない.
プログラミングという技術(とかスキル)を教えたいのか,本質は何かを教えたいのか.