プログラミングをはじめて学ぶのに最適な言語はなにか再考

先のstoryにて、awkがいいだろうと述べた:

awkがいいだろうという意見には、反対もあるだろう。それは承知している。そこで、具体的な言語から離れて、求められる条件を考えてみようと思う。

Scratchなどは、わかり易さを重視しているように思う (デッドコピー(?)であるsmalrubyも同様だ)。グラフィカルであること、その記述(?)方法など、わかり易さが重視されているとみなす理由はあるだろう。だが、同時に、そもそもの言語、つまりSqueakとrubyの持つ機能をユーザーに対してはかなり捨てている。捨てていないとしても、それは背後に隠れているか、すくなくともユーザの手がすぐに届くところからは遠ざけられている。ならば、Squeakやrubyをそもそもの元の言語として使う理由はない。

ここから、2つ言えることがある。第一に、言語そのものがシンプルであること。それは、児童・生徒への教育用として、機能を隠す必要もないほどにシンプルであるということだ。第二に、言語そのものに一貫性があることだ。2つめについて補足すると、ScratchやsmalrubyからSqueakやrubyへと、ユーザはそのまま移行することはできない。まぁ、すくなくともそのまま移行するのは難しいだろう。

ここで、既存の言語において当てはまるだろうものは、lisp系とforth系におおむね限定される (lisp系ではなく関数型言語という声もあるだろう。それももちろんありだと思う)。

lisp系とforth系と言ったところで、やはり「それらはやっぱりシンプルとは言えない」という声もあるだろう。基本の要素や基本の文法を考えてみて欲しい。どちらも最小限の文法や要素だ。lispについては、(基本的には)パーレンを用い、その中において関数や演算子を前置する。これは、人間が構文解析を行っていると言うこともできる。forthは逆に、ワードや演算子を後置する。どちらも基本の文法はそれだけである。それらが複雑に見えるのであれば、関数やワードが多岐にわたるからだ (実際には特殊形式などもあるが)。それは言語そのもののシンプルさとは矛盾しない。それらの言語はシンプルであり、基本的には一貫性がある。

この2つの条件で大丈夫だろうか。実はもう二つ付け加えておきたい要素がある。その一つは直交性だ。これは、関数の合成と考えてもらってもいい。任意の関数fと任意の関数gの合成関数が、可能な限り自由に行えるというものだ。 g(f(x))と書いたり、 g○fと書かれたりする (○は*などと同じくらいの大きさの一種の演算子のようなものだが、ここでは通常の○を使っている)。じつのところ、これが難問だったりする。さらには、合成の前の段階、つまり普通の関数や演算子の段階で、問題であったりする。

たとえば、今日は6月20日だ。そこでこのように書いたとしよう:

Jun = 6
Jul = 7

そこで Jun + 1 によって、 Jul 、つまり7月を求めたいとしよう。だが、それはできない。ただ 7という答えが出てくるのみだ。やりたいことを実際にやるためには、ちょっとデータを用意してやって、それに対しての処理を書いてやらなければならない。月の名称を使ったが、この問題は実はの問題だ。数字 123 の長さを(そのままで)求めてやることはできないし、文字列 abc+1 してやることもできない(これは微妙に言語によるとも言えるが)。もちろん、 Jun + 1 によって Jul というリテラル(?)を求めることもできない。

プログラムを書いたことがある人なら、型キャストを明示しなければならないという経験があるだろう。 g(f(x))という場合、 g(型キャスト(x)) における 型キャスト(x) が、 f(x) に相当しないことは自明としていいだろう。

実は、gawkの場合、あまり型キャストを意識しなくていい。もちろん、明示する必要がある場合もある。だが、他の言語に比べると、明示が必要な場合はかなりすくない。先にawkを提案したのは、そういう面もある。

この、直交性の確保が難しいのは、型やあるいはクラスを厳密に扱うという流れによるものでもある。それはそれで利点が大きいのだが、直交性の確保には、少なくとも型キャストというひと手間が必要になる。

こんな話が児童・生徒向けのプログラミング言語において必要なのかという話もあるかもしれない。そこでたとえばだが、ゲームを作るとしよう。そしてその得点(仮にinteger)を画面中央にセンタリングして表示するとしよう。センタリングをするには得点を表示したときの長さが必要になる。つまり、表示そのものはintegerのままで行えるとしても、センタリングの位置決めに際しては、おおむねではあるがintegerからstringに型キャストし、そのstringの長さを求めた上でどうのこうのしてやらなければならない。

もちろん、Scratchやsmalrubyではそのあたりの処理は隠されているだろう。だが、隠されているということは、ユーザ(児童・生徒)が後から見れば、設定の後出しをされたようなものだろう。その点において、言語の一貫性に疑問を持ちもするかもしれない。

あるいは、言語によっては "abc" * 3という記述も可能だ。そのような言語では "abc" * 3 の結果が、 abcabcabc だったりもする。これはなぜなのか。あるいはこのような例も直交性が確保されている例と見る人もいるかもしれない。だが、 “abc”の長さである3に3をかけた9が結果ではいけないのか。あるいは、なぜ "abc"^3 と書いてはいけないのか。ドキドキドキ²と書いたりするではないか。これは言語の設計においてそうしたというものであり、これ自体は直交性とはまた別の話だ。

だが思い出してみて欲しい。型キャストでミスった経験がない人はいないだろう。児童・生徒は間違いなくここでミスる。ミスるだけならかまわないが、そこでどういう指導が行なわれるだろうか。おそらく:

ここが間違っている

という指導が行なわれるだろう。だが、それは間違ってはいないのだ。言語仕様上において、それを受理しないというだけだ。書けないことと、受理できないことの区別は重要だ。児童・生徒が、そういうミスった書き方をしたとしよう。ミスっていても、それは書けている。だが、受理できない

ならば、はじめから直交性をできるだけ確保した言語を用いるのがいいだろう。

直交性の話が長くなったが、最後の一つは機能だ。あたりまえの話だが、トイ言語であるよりも、実用に使える言語の方が望ましい。だが:

児童・生徒に多くの機能を理解できるのか?

という声もあるだろう。それは、先に挙げたシンプルであることと、一貫性、そして直交性によって確保できるだろうし、それらによって確保する必要があるものだ。

実を言うと、もう一つ付け加えたい要素がある。だが、これはすこしばかり難しいだろう。だが、あえてあげると、手続き型、関数型、論理型のすべての要素を持った言語であることだ。このあたりについては、javascript、あるいはjavascript + なんかのライブラリはどうだという声もあるかもしれない。その場合、訊ねたいのは、「それ本気ですか? javascriptですよ?」というものだ。

なんにせよ、「この言語が適切だ」と言うのは難しい。電子黒板やタブレットの導入時のように、あれな人が主導する方向で決まるということだけは、なんとか避けて欲しいものだと思う。


Show your support

Clapping shows how much you appreciated PsychoHazard’s story.