Hatena::ブログ(Diary)

=== SANDmark 19106 === beginning stress test このページをアンテナに追加 RSSフィード

2012年04月01日

Lispのシンボル、Schemeのシンボル。それぞれの違いがもたらすマクロの実装

だいぶ前、7,8年くらい前ですかね。

CommonLisperである黒田さんのこの記事を読んで、
当時Schemerだった僕は完全にCommonLispへと宗旨替えしました。*1
端的に言えば前述記事の通り、たしかにCommonLispのシンボルはファーストクラスで、
Schemeにおけるシンボルはファーストクラスではない。
そう思っていました。*2

しかしTwitter上での僕のなんてことのないつぶやきに@を飛ばしてくれた方がいました。

参照先はScheme処理系Gaucheの開発をなさっているShiroさんによる、
上記黒田さんの記事への言及です。

長いことS式を見ていなかったので読むのに少し苦労しましたが、
つまるところ @anohana さんのおっしゃる通り「見解の違い」という表現がしっくり来ます。
すなわち「シンボルがどうのこうの」というLisp - Scheme間の問題はマクロから来ているわけで。

CommonLispもそうでないとは言い切れませんが、
Schemeは概して学術的かつ専門的で、皮肉って『黒板言語』なんて言われたりもしています。*3
Schemeにおけるマクロorシンボルの定義はすでに何十年も議論されていて、
それだけ活発であると同時に、マイナーであり、素人の入り込む余地は限りなく少ない。

事実、僕の頭では回転率を120%、あるいはそれ以上に引き上げなければ
前述の記事の内容を理解することはできません。
一人のコーダーとして未熟だということももちろんありますが、
Ruby作者であるmatz氏(no title)によれば

Rubyは「普通の人」むけ言語だ。ALGOL系の文法だし「普通のプログラマ」にわかりやすい。
対して、Lispなんかはやっぱり頭の良い人向け言語だ。(最近のRails勉強会@東京まわりでは青木さんの「ふつう」シリーズに因んでこの種の頭のいい人を「ふつうの人」と呼ぶ)
最近はHaskellブームだったりして関数型言語の台頭というか復権というかが目覚しいけれども、「あと10年ぐらいするとこの潮流の中からHaskellのアイディアを継承した『普通の言語』が出てくるかもしれない」とMatzは言う。

とのことです。
Lisp狂信者である僕としては「全てはLispから始まりLispに還る」と思っているわけなんですが、
matz氏はそもそもマクロ懐疑論者なので、
Ruby(MRI)にマクロが導入されることはおそらく無いでしょう。*4

普段Rubyを使っている身としては『マクロ』についての理解がおろそかになっていたことは否めません。
しかし今回の指摘で、少しではありますが理解が深まったと思いたいです。
これをTwitterに埋もれさせておくにはあまりにももったいないと思ってエントリにしました。

PracticalCommonLisp(実践CommonLisp)の共訳に参加させてもらったときのお話

当時、僕は10代のへなちょこでした。
計算機プログラムの構造と解釈も読んだけれど、実用レベルには達していない、そんなレベル。

だから今度は興味本位で
「CommonLispとかおもしろそー^q^」などと思っていろいろウェブ上の情報を集めていたら、
なんと Practical Common Lisp の全文がまるまる公開されているではありませんか。*5

しかし日本語版は出版されていない様子。つまり英語。
そのままリーディングして理解できるほど脳のスペックは良くないので、
一旦自力で翻訳してから読んで咀嚼しようと、そんなふうに思ったわけです。

Lispと言えばPaul Grahamの名前がまっさきに思い浮かぶかもしれませんが、
彼はどちらかというとSchemeよりで、彼のANSI Common Lispには
CommonLispの代表的なマクロ loop について一言も触れられていなかったのです。

だからPractical Common LispLOOP for Black Beltsの章にはとても感銘を受けました。
forもwhileもdo whileもeachも、全てくるんで抽象化した「ループ処理のDSL」というのは
「まるでプログラミングじゃないみたいだけど、これこそがプログラミングだ」
という、矛盾した感情を覚えたものです。

その章をいざ拙い英語力で翻訳してみると、誰かに見せたくなるのが心情。
しかし法律上、公開には著者(Peter Seibel)の許諾が必要なわけです。
そこで、勇気を出してPeter Seibelさんにメールしてみたのです。

返事なんて返ってくるわけない」と思っていました。
送信したメールの文章はもちろん英語で、後から気付きましたが、
文法も単語も間違いだらけでしたから。

しかし彼は、それでも返信してくれました。

もう日本語翻訳チームがあるから、参加するかどうかは自分で決めて。

至ってシンプルに、そんな趣旨のことが書いてありました。
メールのCCに翻訳チームのメーリングリストのアドレスを表記して。

僕は参加させてもらうことにしました。
若気の至り……と言いますか、今でも青っ鼻たらした小僧であることは充分承知ですが、
「なんかすごいことになった!」という興奮で胸がいっぱいだったのは覚えています。
英語も、Lispへの理解度も、まったく基準を満たしていないにも関わらず。

19歳でしたから社会経験はありませんでしたし、
かといって「ミスっても大目に見てね☆(ゝω・)v」なんて言えるわけがありません。

メーリングリストのメンバーは全員が立派な社会人で、
同時に各分野のスペシャリストであり、僕だけが素人。

そんな絶対的な壁、いわばATフィールド的な何かを作ってしまって、
僕はメンバーの中でほとんど発言せず、震えながらリポジトリコミットする、
まるで役立たずのような、空気と言いますか、そんな存在になっていました。

担当したのは31章と32章。
それ以外は他の訳者さんが担当しておられたので、
「31章と32章を翻訳します」とだけメーリングリストに送信し、あとは黙々と作業するのみ。
正直、メーリングリストにメールが来るたびに、
情けないことに、泣きそうなほどドキドキしていました。

内容があまりにも高度で、僕が口を挟もうものなら
「え、なに言ってんのこいつ?」と思われること山のごとしだったから。
無論それ以前に、スペシャリストに素人が意見していいはずがない、という怯えもありました。

それでも時間というものは容赦のないもので、およそ2年の時が経過し、
僕は栃木県のとある会社にアルバイトとして赴くことになりました。
19歳から21歳まで、これまでの人生の中で
もっとも濃い期間だったと言っても過言ではありません。

さて、その時点で僕の担当した部分の翻訳そのものは終わっており、
残るのはある意味もっとも重要な「校正」作業。

翻訳が終わった……と言っても、ぶっちゃけましょう、
僕には内容が理解できていたわけではありません。
もちろんLispを知らない人のための文章(英語だけど)ですから、
ある程度までは「なるほどなー」と思っていましたが、
より高度な部分になると、芯から理解したとは到底言えないレベルだったのです。

バイトは力仕事だったので、帰る頃には泥のように眠りにつく毎日。
メーリングリストには「未読」だけが増えて行きました。

そして、Lisp/Scheme界で知らない者はいない、黒田寿男さんと川合史朗さんのお二人。
校正作業でこのお二方が招かれ、僕は感激すると同時に絶望しました。

  • 現人神と接触できた!
  • 現人神に自分の文章を読まれるorz

僕のLispに関する知識は本当に「知ったかぶり」で、
実用的なプログラムないしスクリプトのようなものを書いたこともなければ、
ましてや30章、31章にあるような「DSLを作る」なんて
プロ中のプロしかしないんだろうな、と思っていましたから。

そんな高度な技術の解説を、ド素人が翻訳して、神に読まれる?
僕にとってこれ以上の拷問はありませんでした。

今でこそ、チャンスだったという考えもあると言えばあります。
しかしその場はあくまでも「本を翻訳するメーリングリスト」。
「僕が神に質問していい場所」では決してなかったのです。
他の考え方ももちろんあるでしょう。
単に当時の僕が、自分で自分を追い詰めていたということなんです。

結局僕は校正作業にはまったく参加できず、何一つ貢献できませんでした。
社会経験も、知識も、理解力も、英語力も、コミュニケーション能力も、
なにひとつ備え持っていなかった僕にとっては、
「自分がいない方が、より素晴らしい出来になるのではないか」
そう思わせるに充分なプレッシャーが、そこにはありました。

かくして本は「実践Common Lisp」という題名で出版されました。
そして、翻訳に参加したという理由で3冊、初版が献呈されました。

僕の心の中には「迷惑をかけてしまった」という後悔の念が渦巻いていて、
献呈された本を眺め、表紙に僕の名前が載っているのを見ては、*6
名声欲が満たされることもありましたが、複雑な、
語弊を承知で表現するなら「恥ずかしい」という感情も抱きました。

しかし当然、評判は気になるもの。
別の方が翻訳した30章と、僕が翻訳した31章とは前後編になっているのですが、
出版されてしばらくした後、ネットで検索をかけてみました。

これは良書だな。30章と31章が特に素晴らしい。

そんな文章がヒットしました。

僕は泣きそうになりました。たったそれだけの一言で、全てが救われました。
自分がLisp界にほんのわずかでも貢献できたという事実が、
その過程で周りの方にどれだけ迷惑をかけたかを差っ引いても、
感激で胸がいっぱいになったんです。

ここまで「自分がどれだけ苦労したか」という愚痴を延々と披露してきましたが、
僕が言いたいのはただひとつ。

「この本は素晴らしい方々によって生み出された、素晴らしい本だ」

それに尽きます。
恥ずかしながら「素晴らしい方々」のうちには自分も含まれることになりますが、
それでも胸を張って「良書だから読め!」と僕は言いたい。

そしてこの場を借りて、迷惑をおかけしてしまったことを関係者各位にお詫び申し上げます。
同時に、素晴らしい経験をさせてくださり、心から感謝しております。
ありがとうございました!

こんなエントリをここまで読んでくれた方にも。ありがとうございます!
これを機にLispに興味を持ち、Lisperになっている方がいたらこれほど嬉しいことはありません。
またすでにLisperだよという方も、この本でスキルアップを計ってくれたら嬉しいです。

もちろん、「もう読んだ」なんて方もいらっしゃるでしょう。
そんな方は批評をフィードバックしてくれたらとても喜びます。主に僕が。

再三言ってきたとおり、僕はLisperと呼べるレベルではないのは確かです。
だからみんな、一緒に勉強しようぜ☆(ゝω・)v

*1:今はRubyistを名乗っていますが、同時にCommonLisperでもあります。そして、どちらもドのつく素人です。

*2:実際Schemeのシンボルはファーストクラスではないんですが、「シンボルと識別子」という形で実装されているらしいです。

*3:もっともそこには「実用的なライブラリorソフトウェアが無いってことは黒板上でしか楽しめないだろ」というニュアンスが多分に含まれていますが。

*4:コードの断片をパースツリーにしてくれるruby2rubyなんてのもあります。

*5:最終的にLispでMP3ストリーミングサーバを構築しよう、という趣旨の本。

*6:ちなみに表紙に掲載されている訳者の一番最後(右側)が僕です。