Skip to content

Instantly share code, notes, and snippets.

@omasanori

omasanori/gist:8023683

Last active Dec 31, 2015
Embed
What would you like to do?
R'0'RSを読む

R'0'RSを読む

これはLisp Advent Calendar 2013の19日目の文章です。

はじめに

表題に出てくるR'0'RSは正式な名称ではありません。表題で私がR'0'RSと呼んでいる文章はSchemeの言語仕様を記述した報告書、いわゆるRnRSの元祖といえる"Scheme: An Interpreter for Extended Lambda Calculus"です。この文章はAI Memo 349としても知られています。以下ではAIM 349と呼びます。

AIM 349はSchemeの初期設計者であるGerald J. SussmanとGuy L. Steele Jr.の記した一連の論文"Lambda Papers"の最初の一篇であり、Schemeの初期の様子を知ることができる重要な資料です。

私が初めて読んだRnRSはR5RSでした。当時の私に表示的意味論を読み下すことは荷が重く[1]、それ以外の部分を読んでいました。導入に書かれた有名な一節「プログラミング言語は機能の上に機能を積み重ねるのではなく、さらなる機能が必要となるような欠陥や制限を取り除くことで設計されるべきである (Programming languages should be designed not by piling feature on top of feature, but by removing the weaknesses and restrictions that make additional features appear necessary.)」を読んだときに感じた驚きと共感は今でも心に残っています。

今月の頭にふと思い立ってAIM 349をダウンロードして読んだとき、私はR5RSとはまた違った驚きを得ました。今回はAIM 349を読んで私が感じたことをつらつらと書きだそうと思います。

時代を感じる記述

AIM 349のは1975年に発行されました。そのため、使われる用語や比較対象となるプログラミング言語も2013年とは少々異なっています。

例えば、特殊形式を説明するときにはfexprやfsubrという単語が登場します。これらは初期のLISPに存在した「引数が評価されずに渡される手続き」ですが、Common LispとSchemeはマクロによってそれらを置き換えました。また、冒頭にある"SCHEME is essentially a full-funarg LISP."の一文も普段から特に意識することなくレキシカルクロージャを使い、funarg問題という単語を耳にすることも少ない現在からするとなんだかくすぐったい感じがします。識別子がすべて大文字で綴られている点からも伝統的なLispらしさを感じます。

他にも、手続きの機能を説明するときによく「これはMacLISPのxxxだ」といった表現が登場します。MacLISPはMITで開発されたため、MITの同僚と意見を交わす際には他のLisp方言と比べてもより適切な比較対象だったことが想像できます。私からすると「これはMacLISPの『新しいスタイル』のDOに似ている。古いスタイルのDOはサポートしていない」などと書かれてもピンときませんが、38年後の人間が当時の人々のために書かれた文章を読めばそのようなことは致し方ないのでしょう。

実装上の注意や利用例に多くのページが割かれている

R5RS以降の最近のRnRSしか詳しく読んだことのなかった私には新鮮だったのが、純粋に言語仕様のみを記述した部分が少なかった点です。言語仕様を記述した第1章が5ページあり、その後は第2章で継続渡しスタイルや末尾再帰、マルチプロセッシング(!)を含めた機能の利用例を紹介し、第3章で置き換えモデルを説明した後、第4章と第5章は丸々実装について論じています。特に第5章はMacLISP上の実装コードを解説付きで掲載していて、実装に中立な言語仕様書である現在のRnRSとはまったく印象が異なります。

現在のRnRSを『Schemeの報告書』として認識していた私からすると、実装者としてのコメントにあふれているAIM 349は何とも言えない親しみを感じつつ、わずかな違和感も感じます。

プロセス

SchemeはSussmanとSteeleがアクター理論の理解を深めるべく実装した小さなLisp方言として始まりました。そのことをよく表しているのがCREATE!PROCESSやSTART!PROCESS、STOP!PROCESSといったプロセスを扱う手続きです。また、EVALUATE!UNINTERRUPTIBLYは内部の式が評価されるまでの間は他のプロセスに割り込まれないことを保証する排他制御機構を提供します。単語の区切りとして!を使っているのも新鮮で面白いと私は感じました。

今のRnRS Schemeからこれらの機能は取り除かれていますが、元々Schemeはアクター理論への貢献で知られるCarl Hewittが設計したPlannerに関連付けてSchemerと呼ばれていた、というエピソードをどこかで目にしたことがあった私はプロセスがAIM 349にあることを知ったときに感動を覚えました。

おわりに

今となっては実装するために参照されることのあまりないAIM 349ですが、そこにはSussmanとSteeleが当時どのように考え、問題の解法を見出したかが理論と実装の両面から記されていました。言語設計者のインタビューなどを読むのが好きな私にとって、AIM 349はとても興味深い読み物でした。

まだAIM 349を読んだことがない方はMITにアーカイブされているAIM 349のPDF (ftp://publications.ai.mit.edu/ai-publications/pdf/AIM-349.pdf) をダウンロードして読んでみてはいかがでしょう。

断念したネタ

先日のカーネル/VM+K*BUG勉強会@関西 ごかいめ@syuu1228OSvを紹介しているのを観て、これでGaucheを動かせば面白そうだと思っていたのですが、Gaucheは比較的大きかったのもあってなかなか動かせませんでした。

そこで@wasabizpicrin [2]にターゲットを切り替えたのが今朝のことでした。picrinを含むイメージを作成することには成功しましたが、picrinを実行しようとするとELFローダがエラーを起こして中断され、REPLの実行にたどり着きませんでした。もう少しだと思うのですが……。アドベントカレンダーには間に合いませんでしたが、未練があるのでまた時間をとって取り組みたいです。

[1]今でも理解できていると自信を持って言うことはできません……。
[2]Lisp Advent Calendar 12日目: 2ヶ月半でR7RS準拠のscheme処理系作ってみたはもう読みましたか?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment