Scheme:Schemeプログラマのレベル10

Scheme:Schemeプログラマのレベル10

emeitchさんのリクエストより。元ネタは Perlプログラマのレベル10

私家版、Schemeプログラマのレベル10

くれぐれも本気にしないように。

レベル0

SchemeとかLispとかいうカッコだらけですごくわかりにくい言語があることは知っているが、 最強とか主張する信者がいるらしいのでなるべく関わらないようにしている。

EmacsLisp?もその親戚らしいけどコードを見ただけでくらくらする。 でも便利なマクロは自分の.emacsにコピペしている。

レベル1

Schemeに関するwebサイトを見たり、大学の講義での説明とかを聞いて、 factorialとかappendとかreverseとかを書いたり、 ネストした木構造のノードの数を数えたりできる。 でもそれが何の役に立つかわからない。こんな言語で実用的な プログラムが書けるなんて信じられない。

カッコの位置を間違えて動かないプログラムのデバッグに1日費して嫌になる。

レベル2

湯淺さんの「Scheme入門」(isbn:4000077015)、 Dybvigの「プログラミング言語SCHEME」(isbn:4894712261) あたりを見ながら、例題をちょこちょこ書いてみる。 特定の処理系について、入出力ライブラリやコマンドライン引数の 扱い方を覚えて、自分でもちょっとしたスクリプトを書けるようになる。 でも、自分で書くコードではlet*やset!を多用してしまう。 ループはdoを使うが、forループが欲しいと思う。 再帰のありがたみはまだよくわからない。

SICPも買ってはみたけれど、ちょっと読んでまだ難しそうなのでお休み。

プログラムの動作が処理系依存のふるまいなのかSchemeの仕様に沿った ものなのかについてあまり意識しない。

継続という言葉の響きに憧れるけれどそれが何を意味するのかわからない。 でもなんだか凄そうだとは思っている。

レベル3

mapの便利さに目覚めて、なんでもかんでもリストにしてからmapしまくる。 letrecやinternal defineによるローカル関数定義を多用するようになる。

自分のwebサイトのドキュメントをSchemeを使ったフィルタで生成するとか、 普段から使える個人用のプログラムをSchemeで書き始める。 後に、そのコードの半分はsrfi-1とsrfi-13にある関数の再実装であったことに気づく。

call/ccを非局所脱出やコルーチンに使ってみて、 なるほど、確かに動くな、と思うが、それ以上の応用は思い浮かばない。

普段常用するマシンに色々な処理系をインストールしまくる。

たまにC言語に戻った時に printf("%s: %d?n" name value); と書いて 何故コンパイルエラーになるのか悩む。

レベル4

ループを書くのにnamed letを自然に使うようになる。 C言語でもつい再帰で書いてしまうようになる。 何故forループがあんなに欲しかったのかわからない。 クロージャが環境を捕捉する、ということが具体的にイメージできるようになる。 関数を関数に渡すことに抵抗がなくなる。

特定の処理系を深く使い込むようになる。 リストだけでなくベクタやハッシュテーブル、オブジェクトシステム等を ぼちぼち使うようになる。 簡単なコード生成にマクロを少し使ってみる。

ライブラリに不足を感じ、マイライブラリを作りはじめる。

Emacs?でC-M-bやC-M-fなどのS式を扱うキーを無意識のうちに使うようになる。

レベル5

SICPをついに読了する。ambでcall/ccの真の力を知る。 プログラム中にset!があると気持ち悪い。 多値を返すことを不自然と思わなくなる。むしろ多値が返せないと苦痛。 lambda、と意識しないでもタイプできるようになる。

趣味で書くプログラムでSchemeを使うことが増えてくる。 仕事でJavaやC++を使っている時にああここでちょいと クロージャを使って再帰すれば、と思うことがある。 救いを求めてファンクタなど使ってみるが、 (), {}, [], <>などという4種類もの括弧にもはや頭がついていかない。 括弧は()で十分だ。

色々な処理系の実装を読みまくる。

マイSchemeインタプリタを好みの言語で書く。 R5RSの範囲を実装して達成感を得る。 ただ継続の実装はちょっと怪しい。

レベル6

Schemeを使ったソフトウェアプロジェクトを立ち上げる。 仕事場のマシンにもこっそり処理系をインストールして、 日常の処理を自動化するSchemeプログラムを書きはじめる。

プログラムを書いていて少しでも繰り返しがあると、 コードをマクロで自動生成したくなる。

他の言語のデザイナが演算子の優先順位や文法に使う記号の善し悪しを 議論しているのが遠い世界のように感じられる。

ローカル変数束縛とlambda式との間に差異が感じられなくなる。 人のコードを読んでもlambdaが見えなくなる。

既存の処理系のバグを見つけてパッチを送る。もしくは、 既存の処理系の開発に参加する。

あるいは、マイSchemeコンパイラ (Cへのトランスレータ) を書いて、 他の処理系と速度を比べたりしてみる。 ただライブラリが少ないので実用には至らない。

レベル7

comp.lang.lispで「関数と変数の名前空間は別であるべきか 一緒であるべきか」というフレーム合戦に参加する。 comp.lang.schemeで「マクロは健全であるべきか」という フレーム合戦に参加する。

社内向けに作ったwebpageがSchemeを使ったcgiで生成されていることは 知る人ぞ知る事実である。しかし、 仕事で納入した例のJavaプログラムが実はSchemeによって 生成されたものであることは誰も知らない。

ILC?もしくはScheme Workshop?に参加する。

Lisp/Schemeの求人を見つけると心が揺れる。

プログラムを脳内で継続渡し形式に変換できるようになり、 call/ccを特別なものとは思わなくなる。

レベル8

仕事の半分でSchemeを書いている。 かなりまとまった仕事をこなす実用レベルのSchemeプログラムを作成する。 ただそれが表に出ることは少ない。

普段は特定の処理系にコミットしているが、 必要ならばすぐに別の処理系に乗り換えられる。 マクロで互換性レイヤを書くか、Scheme to Schemeトランスレータを 作れるからだ。

R5RSマクロがTuring Completeであることを示せる。 あるいは、R5RSの表示意味論の解釈をめぐってc.l.sで論争する。 あるいは、R5RSの仕様のバグを見つける。

Schemeの最適化コンパイラを書く。相当速くなったところで 「第一級の継続の存在下では正しくないプログラム変換」を行って いたことに気づき、call/ccにアンビバレントな感情を抱く。

ILC?もしくはScheme Workshop?で発表する。

レベル9

仕事でSchemeばかり書いていても何も言われない。 これはすなわち、以下のいずれかのケースを意味する。

  1. 数少ないSchemeプログラマの求人にうまくはまった
  2. 大学のコンピュータサイエンスの教員になった
  3. 自分で立ち上げた会社なので好きな言語を選べた

趣味では複数の関数型言語をたしなむようになる。 もっともそれらの言語のコンパイラをSchemeで書いたりするのだが。

レベル10

3つ以上のSRFIを提出しfinalizeされる。

ILC?やScheme Workshop?にKeynote speakerとして呼ばれる。

SussmanやSteeleとはファーストネームで呼び合う仲である。

R6RS comitteeの一員である。

コメント、議論

More ...