おがさわらなるひこのオープンソースとかプログラミングとか印刷技術とか

おがさわらなるひこ @naru0ga が技術系で興味を持ったりなんだりしたことをたまーに書くブログです。最近はてなダイアリー放置しすぎて記事書くたびにはてな記法忘れるのではてなブログに移行しました。

クリエイティブ・コモンズ・ライセンス
特に断りがない場合は、本ブログの筆者によるコンテンツは クリエイティブ・コモンズ 表示 - 継承 4.0 国際 ライセンスの下に提供されています。

知識と知恵と電子教科書

ニーズあるんかいな、と思いつつリクエストがあったので、ついったからのコピペにちょびっとだけ補足。

前提

昔tobesetuで小野田セメントの南沢さんのお話をさせていただいたときに、すでにこの問題意識はあったので、暇な人はこのブログか slideshare から探してくだされ。

パラメトロンを発明された、当時東京大学和田研究室の後藤英一さんは、後日親しくなったMIT のマッカーシーに「面白いことを考えたな、なんでそんなに遅い素子を作ったんだい?」と聞かれ、「しょうがないだろ、金がなかったんだから」と答えたとか。

情報も同じだと思うんだ。
今ってなんでも情報手に入るじゃない。ネットさえつながれば即時に、無限に。
だから即時に出てくる情報を一生懸命記憶することの意義がどんどん低下していると私は考えている。
逆に情報がありすぎちゃって、「ゼロベースで何かはじめる」ことに対して対応能力が非常に落ちているのではないだろうか、と今の若い人を見ると思ってしまったりする*1

じゃあそのために何が必要かということ。

ついったからのコピペ

スクリーンキャプチャとかはしないよ、めんどくさいから。

……ちょっと言葉遊び的ではありますが、辞書的、百科事典的定義を知っているのは「知識」でいいですね。そういうのの上に立つのは「知恵」と呼ぶべきものかも。そして知恵を磨けば知識は表層的でかまわない、と。

というかぼくの思うところの知恵というのは割と濫読というか「使うことを目的としない知識を黙々と貯めこむ」ことで、ある日それが発酵して湧いてくるような気がします。引き出しの数というか。

と考えると、ネットでモノ調べすることの一つの欠点は目的にたどり着きやすすぎることじゃないかと思うのですよね。無論、目的を果たすにはそれでいいのだけれども、「効率を上げる努力をしない」「もっかい検索すればいいと思うので記憶に残らない」という点はあると思うのです。

ただしネットの情報は膨大だし玉石混淆だから検索技術がないと使いこなせない。ならどうするか、というと、やはり若いうちに読書をたくさんしておくのがいいんじゃないかなと思ってます。

本のいいところは出版にそれなりにコストがかかるのである程度の選別がされていること、数も少ないので良書と悪書の評判も蓄積されること、検索性が悪いので読み手の技術が鍛えられること、かなぁと。通り一遍読んでタイトルと目次だけ覚えていれば、知識のマッピングができる。

ということでぼくは教科書の電子化に消極的反対なのです。必要じゃないところを授業中に読みふけって先生に怒られる醍醐味がなくて、なんで学生なんてものをやる意義があろうか。学生のときに必要なものは、検索によって捨てられるところにあると思う。


まあ、勝手な俗説ですがね。
少なくとも大学1・2年ぐらいのときに図書館に篭って面白いと思える本を濫読するって時期があってもいいと思うんですがねえ。というか、大学なんて施設はそういうことに使うためにあるとぼくは思っているんだけど。受身で授業を聞くことなんかより、そういうことはずっと価値がある。

*1:おっさん臭いな、俺。

プログラミング入門にふさわしい言語とは?【その2:職業プログラマーを目指すには】

d:id:naruoga:20091009:1255062099 に引き続き、やっと最終回*1
簡単にさらっと意見をまとめようと思っていただけなのに、なんで三回シリーズになりますか俺。文才ないな。

えー前回と話変わって、職業としてプログラマーを目指す人向けのプログラミング言語談義です。
こっちの方は前回よりもはるかに多彩な意見が存在することが予想され、私ごときではなんらかの結論を出すことはできません。ので、思いついたトピックをだらだらと語っていく形になります。
異論反論はコメントなりトラバなりはてブなりでしていただければと。

前提

大事な前提を前回書いてなかったんですが、これまでのエントリはプログラミングを学ぶ側、教える側、どっちに向いていたでしょうか。
基本的には学ぶ側も向きつつ教える側へ、という感じだったのですが、学ぶ側へ投げかけるには前提とする知識がちょいとアレでソレな気がしました。特に前回。

ので両方に色目を使うのはなしにして、

  • プログラミングを教える立場の人
  • プログラミングを自習する立場の人

に対象をしぼりたいと思います。片方向で授業を受ける立場の人は対象にしませんよ、ということです。なぜならばそういう人たちには選択肢がないわけですから(授業で教えてくれる言語以外は選びようがない)。

職業プログラマーが学ぶべき言語の要件

前回のエントリでも同様のことを述べましたが、要件の設定はこちらの方が緩くなります。「え、逆じゃないの?」と思う方もいらっしゃるかもしませんが、そーではありません。

なぜなら、職業プログラマーを目指す人間がただ一個の言語を学ぶだけで満足していいはずがないからです。ですから、ある言語では満たされていない要件が別の言語で満たされていれば十分。そのなかで、「最初の言語はなにを優先するか?」ということになります。

例によって私見ですが、考えられる要件は次のようになるのではないかと思います。

必須要件
  • 手続き型言語であること*2
  • 文法がシンプルかつ明瞭であること
  • 処理、ループ、分岐の三要素を制御構造として備えていること*3
  • 基本的なアルゴリズムやデータ構造を実現、あるいは利用できる言語であること*4
  • グローバルスコープ、ローカルスコープの概念があること
付加条件
  • オブジェクト指向言語であること*5
  • 十分に強力なライブラリ群を有すること。あるいは外部ライブラリを簡単に参照できる仕組みがあること。
  • 前記ライブラリを除き、言語単体で閉じていること。つまりテンプレート言語の類でないこと*6
  • 引数の値渡しと参照渡しが概念として明確になっていること。

よくよく考えたらまだ出てくるかもしれないですが、ひとまずこんなもので。思いついたら追記するかも……。


さてこれらを踏まえて、あとは与太話を……。

「C 言語を通っていないプログラマはダメ」は本当?

この話を書きたくてここまで来たようなもんです。

プログラミング入門言語としての C 言語

まず前提として「入門言語としての C 言語」については、正直当落線上でしょうね。
その一番の理由は、言わずとしれたポインタです。
C のポインタはアセンブラの間接参照を生で見せたようなところがあり(いや、実際そうなんですが)、なおかつそれに文字列操作やら参照渡しの機能を持たせているため、「このポインタはどのコンテキストで使われているの?」ということを常に意識しないとあっという間に混乱します。
このように、(プログラミングとして)本質的でないところで悩ませる言語は、入門に最適とは必ずしも言えないでしょう。
実力のあるメンターさんが適切なテキストを用いて、始めて C でのプログラミング入門は成り立つ、というのが私の持論です。

C を通るべきか否か、その二つの考え

「C をやらない奴はダメだ」という発言を眺めていると、二つの傾向がある気がします。

一つ目は、「俺は C でやってきた、だから今の俺がある、だから C でやるのがいいんだ」のタイプ。いや、結構多いですよ、こういう人。「SEED から見た奴はガンダム語る資格がねえ」とか「アラカン見てない奴はチャンバラ見たとはいえねえ」みたいな感じかな。
こういう人に「C で教育を行わなければいけない理由はなんですか」って聞くと「諸説有るだろうけれど、C が最高の言語の一つであることは間違いなく、だから学ばなければならない」とか答えになってないことしかいってくれないので、こういうタイプはさっくり無視しましょう。

二つ目のもっと腑に落ちる回答は「C のように資源管理を自前でやらないといけない言語を経験しないと、自分のプロセスがどれぐらいメモリを食っているかとか、そういうことを考えて設計できなくなる。だから C をやることは大事だ」というもの。うん、これなら私も分かります。
ただし、「自分のプロセスがどれぐらいメモリを食っているか、そういうことを考えて設計」しなければいけないことが必須であるならば、という但し書きをつけます。
つまり言語やプラットフォームが頑張って、GC とか階層ストレージとか使いまくって、どんだけでかいメモリを alloc しようがパフォーマンスを落とさないような環境。そんなのがあるかどうかは知りませんが、そういう環境でだけ仕事すればいいなら、資源管理なんて意識する必要ないですよね。

資源管理といえばもっと小さな例で言うと資源をオープンしたまま関数がエラーで落ちちゃってその場で return したら資源リークする。これだって ruby とかなら begin - ensuretry - finally Win32 の構造化例外と間違えた (^^;) 使えばいいわけで、これを自分で意識「しなければならない」理由は少ないと私は考えます。

ただし、C が素晴らしく有効なところ、それはコンピュータアーキテクチャを学ぶときの副読本をして見るときで、アーキテクチャの勉強がしたいなら、手段として C は必須になります。高水準言語の記法で、低水準にアクセスできるのですから。「C は高水準アセンブラ」という言葉はこういうときに生きてきます。
また Linux カーネルRuby のソースなど、C でかかれていて面白い題材はたくさんあります。こういう物に手を出すなら、当然 C は必須です。そりゃそうです、「道具」ですから。

C 言語談義まとめ
  • C をやらないプログラマはダメ、というのは幻想に過ぎないことも多いですが、資源管理を学ぶという意味では一理あります。
  • しかし資源管理を意識しなくても問題ない状況もたくさんありますし、将来に於いては資源管理を意識できないプログラマがダメである理由が消滅する可能性もあります。
    • 「C もできない奴は」という人はそういうことを念頭において発言していただきたいです。
  • ただし、C という道具を手にしていれば掘れば掘るほど金脈が出てくる、そういう分野はたくさんあります。そういう分野に手を出すために、C の知識を棚卸するのはとってもいいことだと思います。

Ruby

オイラがプログラミング言語教育でなんか一個選べ、と言われたら ruby を挙げる可能性が高いと思います。

メリットは:

  • 文法がシンプル、かつ理解しやすい。
  • クラスの数が少ない*7
  • モジュールの mix-in の考え方はわかりやすい。
  • 宣言文が少ないので、記述量が少ない。したがって理解が早い*8

10.10 追記

  • 動的型言語であり、型について意識しなくてもいいことが多いこと。
    • 別に JavaC++ のような静的型言語が悪いという意味ではないです。ただ「入門」としては、一つでも意識する必要があるものが減った方が本質が理解しやすいでしょう。

一方で、デメリットと言うか、これどうしようかな、というのが、

  • オブジェクトの考えが骨格にいるため、オブジェクト指向を早い段階で導入する必要があるが、これが悩ましい。
  • ブロックの概念もどう教えるか。IO.open のブロックとか超便利なんだけど、意味をわかりやすく説明できるかというと……。Array.each なんかもそうですね。
  • 例外も初めてのプログラミングというにはちょっと重たいか?
  • Gems とかを教えるべきかどうか。教えるとしたらどんなやり方がいいか。
    • なぜ Gems で悩むかというと、車輪の再発明をしない、というのは今のプログラマにおいて重要なスキルであると思うからです。もちろん PerlCPANPHPPear も同じ。ほしいものが有ったらまず探す。探してる手間ももったいなくてパッと作れちゃうなら作るって解もあるけど、割と手間がかかるモジュールを一生懸命実装したらもっといいのがもうありました、じゃ悲しいでしょう?
  • インスタンスメソッドやモンキーパッチングのような Ruby っぽい話を入れるかどうか。後者はともかく前者は話したい所だけど、頭がいい人なら思いついちゃうよね。んで話がそっちに引っ張られないかが心配。


なおあくまでも「プログラミングの入門」なので Rails とかは対象外です。

私なりの感触は、オブジェクトの壁さえなんとかなればいけるかなって感じです。少なくとも JavaC# で教育を行うよりかはよい効果が得られそうに感じています。理由は ruby が big class であることと宣言がないことです。少ないことと、動的型言語であることです。*9

Pascal と Modula-2 と Oberon

Pascal について知らない人はいます? いませんね? といいたいところなんだけど、もう知らない人多いんだろうなぁ。
チューリヒ工科大学 (ETH) の N. Wirth (ニコラス・ヴィルト) という人が作った教育用言語です。コンピュータの実装から離れてアルゴリズム記述をできる言語という目標を掲げた Algol ファミリー、主に Algol 60 の影響を強く受けています。

C と Pascal は対比されることが多いのでここでも C との違いを列挙してみましょう。

  • Pascal では関数は入れ子構造を持つ。
    • スコープルールも入れ子の内外で適用される。
  • Pascal は 1 パスコンパイル*10を指向している
    • したがって、前方参照 (自分の前方、ソースコード的には下の方) にある識別子 (主に関数と手続き) を参照できない。参照するためにはあらかじめ foward 文で「こういう識別子があるよ」と指定しておく必要がある。
  • 元々の言語仕様では複数ファイルへの分割は考慮されていない。
  • C ではすべて関数だが、Pascal は関数 (値を返す) と手続き (値を返さない) は厳格に区別される。関数で左辺値がないとエラーで怒られる。
  • Pascal の goto ラベルは英語一文字+数字といういかにも「使うな」という形式しか使えない。
    • また break や continue などの goto の糖衣構文も存在しない。おかげで Pascal でコード書くとフラグの嵐になる。ちょっとトホホ。
  • ポインタの使い方が厳格。基本的に「他の変数を指す」目的にしか使えない。
  • 値呼び (call by value)、参照呼び (call by reference) が文法で定義されている

太字で書いた「ポインタの使い方が厳格」「値呼び、参照呼びが文法で定義されている」の二点が、C の学習の補強として Pascal をやったほうがいい、という私の主張の源です。

C は文法を単純にすることを指向するあまり、ポインタにかなり強く依存しています。例えば:

int my_strcmp(const char *s1, const char *s2)
{
    while (*s1 != '\0' && *s2 != '\0' && *s1++ == *s2++) {
        ;
    }
    return *s2 - *s1
}

(実際にこんな関数書いたり使ったりしちゃダメだよ) みたいなコード普通に見ますよね。Pascal では文字列や配列はポインタとしてアクセスできないので上記のようなコードは書きたくても書けません。index を用意して、s1[idx1] のように書かなければなりません。まどろっこしいですが、間違いは少ないです*11

では Pascal のポインタというのはどういうときに使うかというと、いわゆるリンク構造を作るときに使います。典型的なのが線形リスト。

type
  list_cell_ptr = ^ list_cell;
  list_cell = record
                value: Integer;
                next:  ^ list_cell
              end;
  
  ...

  procedure list_add_value(var list: list_cell; value: Integer);
  var
    new_cell: cell_list_ptr;
  begin
    while list^.next <> NIL do
      list := list^.next
    new(new_cell);
    new_cell^.value = value;
    new_cell^.next = NIL;
    list^.next = new_cell
  end
  
var
  list_top : cell_list_ptr;

begin
  new(list_top);
  list_top^.value := 0;
  list_top^.next := NIL;
  add_list(list_top, 10)
end.

久しぶりに Pascal のコードを書いたので間違いもあるかもしれないし、なにせエラー処理もなにも入ってないのでマネ禁ですが、ポインタ (^) の使い方が非常に限定されていることが分かると思います。
たしか上記ソースで list_top^.next = 123 とかはコンパイルエラーで怒られるはずです。したがって C のようにメモリアクセス手段として使うことはないです *12

このように「他の構造物を指す」目的にポインタの使用を限定することで
C のような混乱を防ぐことができる理由の一つになります。

もう一つ C のいやらしいのは、基本的には値呼びしか存在せず、参照呼びをポインタで実現していることです。
例えば C で書くこういう関数は (中身は意味無しです)、

void foo(int a, int *result)
{
  *result += a;
}

Pascal ではこう書きます。

procedure foo (a: Integer; var result: Integer);
begin
  result := result + a
end

「値呼び」とは引数の「値」だけを手続き/関数に渡すことで、「参照呼び」とは引数の「参照」を手続き/関数に渡すことです。参照呼びでは引数として渡した「参照」は手続き/関数の外に波及するのがポイントです。C には参照呼びが言語仕様上存在せず、変数へのポインタを値で渡すことで無理やり参照呼びの機能を実現しています。
こいつは C++ で改善されましたが、Pascal では最初から備わっています。ので、この点でもポインタを使う必要がないのです。

ということで Pascal は今それをつかって何か応用するような言語ではありませんが、C のポインタが分からなくなったら学ぶ価値がある言語だと私は思います。
ただ、まともな処理系が少ないんですよねぇ……。GCCコンパイラファミリーに Gnu Pascal がいるのでそれを使うか、あとは Turbo Explorer の Turbo Delphi か。ただ Delphi は非常によくできた処理系ではありますが方言がきついので*13Pascal を学ぶ」というより「Delphi を学ぶ」と割り切った方がいいかもしれません。

なお Wirth はその後、モジュールプログラミングとデータ抽象を持ち込んだ Modula-2、さらにオブジェクト指向化し、Smalltalk のように環境自体をオブジェクトとして自由に操作できる Oberon という環境を作ったりしてますが、まあこういう機能については他の言語で十分学べるのでなにもこんなマイナーな言語で学ばなくてもよいでしょう。
ただし Oberon の動く環境を見たことがある人は非常にまれだと思いますので、デモしてみるとみんなに驚かれたりするかもしれませんね。

Perl/Python

なんでこの子たちが一緒になっているかというとオイラがよく知らないからです (^^;)。

Perl が強力な言語であることは認めます。しかしプログラミング言語を学ぶための教材言語としてはやや文法の自由度が高すぎるのが気になります。つまり「どうとでも書けてしまう」ので、まだ自分のスタイルが固まっていない人が学ぶのはおっかない気がするのです。特に Web 上に散乱する記号の羅列のような不可思議なコードを見ると。
それとも今は「モダン Perl 入門」読め!で済むのかし? それなら選択肢になり得るけど。いずれにせよ、回りに Perl に詳しい人がいる場合前提だと思います。独習は勧めません。

モダンPerl入門 (CodeZine BOOKS)

モダンPerl入門 (CodeZine BOOKS)

Python についてはインタプリタ iPython が強力であること、「Python チュートリアル」が非常によく書けていること*14、などなどから、なかなかいいかな、と思わなくもないですが、日本ではあまり盛んではないこと、他のオブジェクト指向言語では大抵存在するアクセス制御 (private とか public のこと) が存在しないこと、名前空間という概念がちょっと分かりにくいこと、が難点でしょうか。

Pythonチュートリアル

Pythonチュートリアル

でも Google App Engine とかで遊べるのはいいかもですね。

Smalltalk / Objective-C

もともと「自分の環境を自分で好きに触れることこそがパーソナルコンピューティング」という概念を実現するために生まれた Smalltalk

まだ私自身もかじった程度なのですが、今表示してるウィンドウにメッセージ投げるとぱっと表示が変わるとかいうのはかなり強烈な体験なので、かじってみるといいと思います。
あとオブジェクト指向言語というのは結局クラスライブラリ命なわけで、その点オブジェクトインスペクタとかが強力な Smalltalk の環境に早いうちに触れておくのは悪くないかもしれません。
ただし決して仕事に結びつく言語とはいいがたいので、最初に選ぶ言語としてどうかというとちょっと難しいですね。

Objective-CMac OS XCocoa アーキテクチャおよび iPhone/iPod Touch の開発環境として有名です。Smalltalk ほどのインタラクティブ性はないですが、言語仕様は非常に似ているので (C の名前はついているけれど C らしいところはほとんどない、そうです)、Objective-C の予習としての Smalltalk は「アリ」かもしれません。
逆に言うと Apple の環境でしかマトモに動かない (GCC には Objective-Cコンパイラも収録されてますが、フレームワークがなければ意味がないですから……) のをどう取るかですね。

Java/C++/C#

この三つを同時に論ずるなんてコイツものを知らないな、と思ったあなた、その通りです。
基本的に静的型言語、スモールクラス*15、という共通項でまとめてしまいました。乱暴なのは認めます。

えっと、Java については、あなたがプログラマとしておまんまを食べたくて、どうしても一個の言語しか勉強する時間が取れないのであれば、怪我がない選択肢だと思います。
と、なんでこんな一般論でお茶を濁すかというと、オイラ Java ぜんぜん知らないからです。Ruby とかをやってる人間からするととにかく宣言が多くてかったるいというのが印象で、もうすぐ四十郎のワタクシが覚えるのはちょっと骨。が、たぶん Ruby でご飯を食べるより Java でご飯を食べる方が簡単でしょう。PHP の方がもっと簡単じゃね? という話はともかく。

C++ は……最低でも STL、できれば Boost と一緒に勉強しましょうね。
自分でテンプレートクラスが書けるのは当然です。
もし組み込みなどの関係で RTTI 禁止、例外処理禁止、STL も禁止、と言われたら、よほどオブジェクト指向分析・設計に自信がない限り、Better C と割り切り、オブジェクト指向を忘れた方が幸せかもしれません。イケてない人の書いた C++フレームワークほど不幸なものはないからです。

C# は事情としては Java に近いかな。そのかわり MS と心中する覚悟が必要です。まあ Mono プロジェクトにコミットして NetBSD とかに Mono 移植するってことはできなかないですが。

Javascript

実用性といえばグリモンも Firefox 拡張も書けて Web 2.0 もばっちりなコイツはいい線いってると思います。
ただしオブジェクト指向の考え方に少しクセがあるので (プロトタイプ指向といいます)、そこを乗り越えるのがちょっと大変かもしれません。Prototype.js 使えって話もありますが、私は使ったことないので解説はできません。

あと Web 回りでプログラムを書くとしたら Javascript 自体よりも W3C DOM*16 を理解するというハードルが立ちはだかるので、別に Javascript だから簡単に Web 2.0 できるわけじゃないことは認識しておきましょう (^^;)。

Basic

これは完全な与太話です。
そもそも Basic という言語はダートマス大学のケメニーとカーツという二人の数学者が作った言語です。
当時は数値計算には Fortran、事務処理には Cobol、記号処理には Lispアルゴリズム記述には Algol はありましたが実用的な処理系がないという状態でした。

彼らは、数学の道具としてプログラミングを学ぶ学生たちのために、ぱっと書いてすぐ結果が得られる言語が必要であると考えたのです。一種の電卓的言語ですね。

そこで次のような思想が盛り込まれています。

  • インタプリタであること。実行の結果がその場で得られること。
  • 変数の宣言が存在しないこと。電卓を使うのにいちいち変数を宣言しない。
  • ゆえに型宣言も存在しない。後置で記号を書くことで型を示す (たしか独自型は文字列型しか存在しなかったかと)。記号がない「普通」の変数は小数型である。
  • 電卓なので大規模プログラミングの概念は最初から捨てている。のですべてグローバル変数なのは当然。スコープルールは初心者にわかりにくい。
  • 数学者が好む機能として、行列演算やグラフィカル端末を用いた場合のグラフ描画機能などを有する。

ケメニーとカーツの BasicANSI で標準化され、日本でも「JIS 標準 BASIC」として規格化されています。

これらの特徴のうち、最後のものを除いては、初期のパーソナルコンピュータ (マイコンと呼ばれていました) への移植にちょうどいい、小さくてわかりやすい文法でした。
そこでマイコンBasic のサブセットを実装するのが流行り、その一つがビル・ゲイツポール・アレンが書いて通信販売で売り、「ソフトウェアを商売にする」というビジネスモデルを確立した Microsoft Basic です。

そんなわけで初期のマイコンには大抵 MS 系の Basic がついてきて使用者が膨大になったこともあり、マイコンBasic でプログラミングを学んだ人間がよりよい言語……たとえば C や Pascal などに触れることで、「入門用にあえて切った」ところまで批判をする人間が出てきました。
曰く、構造化構文が貧弱である。
曰く、すべてグローバル変数はナンセンス。
曰く、変数を宣言しないのはバグのもとだ。
などなど……。

パソコンの分野では MS Basic と互換性を持ちながらこれらの改善を行う試みがなされました。今の Visual Basic はその完成形の一つと言えるでしょう。
しかし MS Basic との互換性を取るために堅牢な言語であることについては妥協があり、一方で文法が複雑化してしまったため、教育用言語としての Basic の精神は失われたと私は思っています。いや実際便利なときもあるのは認めますけど、VB

ダートマス大学のメンバーも黙ってこの状況をみていたわけではなく、オールドスタイルの行番号を廃止し (互換性のために使うことは許されています)、構造化構文を強化し、関数のローカルスコープを導入し、モダンな言語として再設計しました。
これが ANSI でいうところの FULL Basic、「JIS 拡張 BASIC」です。

この言語仕様に基づく処理系は True Basic として商品化されたのですが、バグバグだった上に MS Basic と互換性がなかったことが猛烈に批判され、ほとんど使われることなく姿を消しました。


この逸話から明らかなことは、

  • 教育用言語としてターゲットを絞って作った言語であっても、その言語に手慣れてしまうと、大きなプログラムを書きたくなる。
  • 言語が普及すると、そもそもの設計思想から離れ、批判を受けることがしばしばある*17
  • それがために元の思想を離れて大規模なプログラムが書けるようにすると、往々にしてそれは元の思想を生かさない形で発展する

ということです。

教育のための言語として何を選ぶべきか……難しいですね。


長々とつまらないエントリをお読みいただき、ありがとうございました。

*1:しかも書きかけで1週間近く放置してしまった。すみません。しくしく。

*2:ここ、いきなり突っ込む人がいるかもしれませんが、世の中で商売のネタになっているプログラムはほぼ間違いなく手続き型言語で書かれているので、「最初のウチに学ぶ言語」は手続き型であるべきだと思います。関数型や論理型はその次のステージでしょう。

*3:これちょっと分かりにくいですが、Fortran IV や昔の BasicDOS のバッチファイルなどで、IF 文の後ろに goto しか書けないようなのはダメ、ということです。

*4:「実現」は例えばヒープソートアルゴリズムを書けること、「利用」は qsort() が使えること、という意味で取ってください。むろん、両方できたことに越したことはありませんが、最低「実現」はできない言語はいろいろ困ります。

*5:これが付加条件かよ! という人も多そうですが、まあ、とりあえずは……。

*6:思いっきり PHP を頭にいれて書いてます。PHP を単体の言語として使うことってあまり聞かないので、単体で学ぶことに意味が薄い、という意味です。もちろん、PHP プログラマになるための職業訓練であれば話は別です。

*7:逆に言えば一つのクラスにメソッドが多いとも言えるけど。

*8:これは有名な話ですが、認知科学の知見によれば、どんなに意味の少ないものであっても(例えば宣言文とか)、行数が多い物はそれだけ理解に時間がかかると言われています。一説によれば人間が一度に認識できる要素数は 7±2 なのだそうです。

*9:宣言が「ない」わけではなくて「少ない」ですね。例えば a = Hash.new は一種の宣言とも言えるわけですから。あと動的型言語については記載漏れなので追記しました。

*10:意味わかんない人は最近新版が出た復刻されたコンパイラ」でも読んでください。雑駁に言えばソースコードを一回舐めるだけで実行コードを生成することです。 (「コンパイラ」って日本では3回出版されてるんですが今のが 2nd edition なんですよね。だから日本で昔出てたドラゴンが表紙の奴の復刻かと思ってたら、今の版は 2007 年に出た改訂版の翻訳であり、復刻というのは間違いだと指摘いただきました。)

コンパイラ―原理・技法・ツール (Information & Computing)

コンパイラ―原理・技法・ツール (Information & Computing)

*11:個人的考えでは、C/C++ でもポインタを使わずインデックスを使用する書き方にした方がよいと思います。余計にローカル変数は使用しますが、今のコンパイラなら最適化で消えるでしょう。

*12:Turbo Pascal では「メモリ配列」「I/O 配列」といって、配列にアクセスすることで実メモリや I/O にアクセスできるゴーインな機能が採用されてました。まぁ当時の Borland のこういうところは大好きですが。

*13:というより、Pascal を実用言語として使うには言語拡張せざるを得ない。

*14:ただし、純粋な入門書というより、Python はなぜこういう言語仕様になっているか、などの話もちょいちょいあるので、ちょっと「この言語がプログラミングはじめて」という人にはノイズになるかも。

*15:一個のクラスに沢山の機能を盛り込まないで、ちょっとずつ違う複数のクラスを用意するという考え方。逆は Ruby のビッグクラス。Hash や Array というコンテナクラスを考えれば思想の違いがわかりやすいと思います。

*16:この際 IE は無視。

*17:Pascal も C の設計者 Dennis Ritchie より「実用言語としては使い物にならない」とてひどい批判を受けています。

プログラミング入門にふさわしい言語とは?【その1:プログラミングの喜びを知るために】

えーとやっと本題でございます。d:id:naruoga:20091008:1255009561 はこの話題の前振りとして、自分のポジショニングを明らかにしたいというところでして。

Wassr などで周期的に話題になるこの件ですが、毎回同じことを書くのも芸がないのでここでまとめて置こうかと思いましてね。

話の発端

大きく分けて二つあります。どちらも周期的に話題に上がります。

  • 世の中には「C 言語を通っていないプログラマはダメだ」とバカにする風潮があるそうです。それは本当なのでしょうか。
  • プログラミングの入門にふさわしい言語というのは存在するのでしょうか。するとしたらその理由はなんでしょうか。

なぜプログラミングを入門するのか

そもそも話はここから始まらないといけないと思うのですが、大抵の人がすっとばしています。それはきっと無言の前提があるからだと思うのですが、当たり前とはいえ確認しておきましょう。

  1. プログラミングの楽しさそのものを教えることで、無味乾燥な道具と思われがちなコンピュータを身近に思ってもらうこと。
    シーモア・パパートの言うところの「構成主義」に基づく教育理論の一部といってもいいかもしれません。つまり与えられた知識を学ぶのではなく、自分たちで考え、物を作り、そこから得られるものこそが真の学びであるという考え。その道具としてのプログラミング。
  2. IT 分野の学徒となりたい、IT でご飯を食べたい、不幸にして? IT 業界に入ってしまった、などの理由で、プログラミングを覚えなければ将来の道が断たれてしまう。

ほとんどの人が 2. しか頭にないのではないかと思います。パパート直系の Squeak e-Toys や SCRATCH を擁する Smalltalker の中でさえ、「Non-Programmer にプログラムの喜びを教える」ということに関心を持つ人は少数派だと耳にしました。
んが、しかし、私はこれだけコンピュータが普及しネットワークがつながった今、プログラミングというあまりにも楽しいオモチャをプログラマだけが独占するのはほとんど犯罪に近いと考えているのであります。

のでまずはほとんどの人間が関心を持たないと思われる 1. から述べ、そのあとで職業としての学問*1、いやちがった、プログラミングはその次に述べたいと思います。

プログラミングの喜びを知るためのプログラミング入門言語

この観点は、先ほど述べたパパートの構成主義の実践としてのプログラミングであったり、あるいはプログラミング経験がまったくないけど Excel VBA や Notes の DB 設計を任せられたりしたアシスタントさんに対してプログラミングとはなんぞや、ということの導入にしたり、といった目的が考えられるでしょう。

求められる要件はつぎのとおりでしょう。

  • 環境作りに苦労しないこと。
  • コンパイル、リンクなどの「おまじない」が不要なこと。
  • できたプログラムが一目で面白いものであること。驚き、喜びを与えられること。
  • 直感的でわかりやすいこと。
  • 日本語のドキュメントが充実していること。
  • Windows で動作すること。
    • 可能ならば他のプラットフォームでも動作すること。

最後の要件は泣く泣く付け加えたのですが、多分非プログラマが所有している環境は圧倒的に Windows が多いだろうと思われるので……。

逆に、以下の点はさほど重要でないと思われます。

  • 作ったプログラムが実用的であること。
  • プログラムのパフォーマンスやメモリ使用量などの非機能要件。

以上を鑑みると候補は以下のようになってくるのかな、と思います。
なおこれは偏見入りまくりの私見なので、人それぞれ考え方の違いはあると思います。あらかじめご了承ください。

SCRATCH

http://scratch.mit.edu/
MIT メディアラボ発、シーモア・パパート、アラン・ケイ直系とも言える子ども教育用プログラミング環境。ソースコードを一切書かない、パレットを並べてプログラミングをするというインド人もびっくりな環境。

この連載が参考になると思います。

マウスだけでもプログラミングできる!(1):非プログラマのためのプログラミング講座
マウスだけでもプログラミングできる!(2):Scratchプログラミングの二歩目、自由な動きを付ける

この連載自体、ここで話題にしていることがまさにターゲットなので、この項目を読んでいる人にはご一読を勧めたいですが、「とにかくプログラミングの喜び、楽しさを教える」という点では大本命だと思います。

各所で行われている (関東だと川口の「メディアセブン」さん) SCRATCH を使った子ども向けコンピュータ教育の現場を後ろから見ているだけで、彼ら彼女らがどんどんプログラミングの概念を身につけていくのが分かると思うので、こういう「プログラマじゃない人のためのプログラミング教育」に興味がある人は見学してみるといいんじゃないかなぁ。


【利点】

  • インストールは簡単
  • マウスクリックだけでプログラムが可能
  • 絵や音をマウスクリックやキーボード操作で動かせるインタラクティブ性が人を惹きつける
  • 条件判定、ループなどといった概念も身につけられる
  • 公式ページによる交換、コミュニケーション
  • 電子回路やロボットとの連動が可能
  • マルチプラットフォーム対応 (Windows, Mac OS X, Linux)*2
  • @IT で連載してる (^^)

【欠点】

  • 他のプログラミング言語へのステップアップに工夫が必要
    • 見た目があまりにも他のプログラミング言語/環境と違う
    • SCRATCH はオブジェクト一つ一つにプログラムが対応する並列プログラミングなので*3、普通のシーケンシャルなプログラムとスタイルが大きく違う
  • 日本語のドキュメントはまだ発展途上かな?
    • 本は一冊出ましたけど。なかなかいい本です。買ってないけど

スクラッチアイデアブック―ゼロから学ぶスクラッチプログラミング

スクラッチアイデアブック―ゼロから学ぶスクラッチプログラミング

  • 教育事例などは増えつつ有るけどまだまだ
Squeak Etoys

http://squeakland.jp/

Smalltalk のフリーの処理系 Squeak にのっかった SCRATCH みたいな環境。というのは乱暴か。時系列的には e-Toys の方が先。
ただし Squeak の場合は最終的に Squeak の世界に降りてこられてソースをかけてしまうので、SCRATCH ほどの純粋さに欠ける気がする。

こっちの方が古いのでノウハウはたくさんあるけど (前記ページに子供向け教材とか載ってるし)、純粋に非プログラマ向けのプログラミング入門環境、という意味であれば SCRATCH の方が(僕は)いいと思うので、利点、欠点は省略します。

なでしこ

http://nadesi.com/

日本女子サッカー代表とは関係ないです。けっこう有名なので私がくだくだ書く必要はないと思いますが、「日本語でプログラムが書ける」が一番のウリでしょうね。
実はあんまり知らないので嘘書いたら誰か指摘くださいなのですが、Windows に特化して、Word/Excel との連携機能もあって、定形業務を自動化する機能を持っています。文法も(日本語であるということ以外)それほどとんがっていないので、SCRATCH などに比べると「実用的」「他の言語への移行が容易」と言えるかもしれません。一方で「日本語である」以外の驚きは少し乏しいかもしれません。

【利点】

  • インストールは簡単
  • 日本語で書ける
    • 面白い
    • 予約語などを覚えやすい
  • Windows に特化しているため、ファイル操作、Word/Excel の連携など日常業務の定形化に用いることができる
    • プログラマから取ってみれば Word/Excel が外部から自分の書いたプログラムで制御できるというのは驚きであり喜び
  • 日本で作られ育っているプログラミング言語であるので日本語のドキュメントが充実
    • 本も出てますしね。買ってないけど。

日本語プログラム言語なでしこ公式バイブル

日本語プログラム言語なでしこ公式バイブル

【欠点】

  • 「日本語で書ける」以外の面白さにやや乏しい
  • 利点の逆になってしまうが、Windows 以外のプラットフォームを考慮していない
Excel VBA

あーそこ石投げないで。
オイラもコイツがプログラミングの喜びを知るのに最高だとは思っておりません。
ただし業務上非プログラマが書く可能性の高い言語であるし、それならば、コイツでプログラミングの喜びを伝えることができるか? そのためにはなにをすればいいか? を考えることは意味があると思うのです。

こいつの場合、やはりなんといっても「普段使ってる Excel が自分の思い通りに動かせる!」ということが最大の武器でしょう。実業につながるのでつまんないっちゃそうなんですが、その驚きをどこまで引っ張ってモチベーションを維持できるかが、教える側の手腕になってくると思います。

【利点】

  • インストール不要 (Excel が入っていれば)
  • 普段使っている Excel がプログラミングの道具になるという驚き
    • データを加工してグラフ化する、などといった定型作業をしている人なら、それが自動でできることに驚いてくれるはず
  • 非常に充実したリファレンスマニュアル
  • マクロ保存機能により、手で操作した内容をプログラムに落とせる
  • Web 上にも出版物もそれこそ佃煮にするほど情報がある

【欠点】

  • あんまりエレガントな文法とは言いにくい
  • コンポーネント」という割と難しめな概念が分からないとコードが書けないのでやや敷居が高い
  • 業務とあまりにも近すぎて、最初の驚きが終わってしまうとモチベーションを維持しにくい
おがさわらなるひこ的には?

私がもし、「プログラムをまったく学んだことがない人にプログラミングを教える」なら、ぜひ SCRATCH でやってみたいと思います。

単純にプログラムの楽しさを教えるなら、SCRATCH でひたすら押し通す。
課題を与えてプログラムを作らせるんじゃなくて、「なんか作ってみてくださいよ、わかんなかったら相談に乗るから」というスタンスで。
自分のアイディアを計算機で実現することによりなにかを得るというのが「構成主義」なわけですからね。

ゴールとしてなにかの言語でプログラムをする予定が有って、その導入、ということであれば、SCRATCH は特殊なところが多々あるので、あまり長い間 SCRATCH に固執するわけにはいきません。基本概念を伝えたら他の言語に移るべきでしょう。
具体的にどの言語か、ということについては、もうちょっとプログラミングの楽しさを別の側面から見せた方がいいかな、と思えばなでしこでもいいと思いますし、いやこれでもうプログラムの経験者だ、だからプログラマとして学ぶべき言語を学ぼう、というなら私の意見としては次回エントリで書くことになると思います。

ということで

極論めいたところもありましたがお楽しみいただけましたでしょうか。
次は「プログラマになるために」と題してお送りしたいと思います。

*1:イギリスの経済学者マックス・ウェーバーの著書の名前。「プロテスタンティズムと労働の弁証法」という名著を持つウェーバーが、なぜあなたはマルクスのように行動しないのか、と学生に詰め寄られたのを、いや、学問とはそういうもんじゃない、と説いた名著。って、なんで俺こんなとこでこんな注釈してるんだろ。

*2:ただし Linux は experimental implementation だそうです。

*3:この点、プログラマの大人がもっと SCRATCH に注目していいと思う理由の一つ。