Lisp quote unquote

Table of Contents

1 はじめに

佐野さんからお誘いを受けて、Shibuya.lisp というところで話す機会をいただきました。 これはそのとき話した内容の議事メモのようなものです。

題が quote unquote とあるように、 1999 - 2002 ごろの comp.lang.Lisp から個人的に面白いと思った発言をとりあげ、 思うところをしゃべる。

2 自己紹介

プロジェクト紹介など、 confidential な箇所があるので省略。

video 配信をお断りしたのもこの理由です。

3 なぜ Common Lisp なのか

一言に Lisp と言っても色々あります。Scheme ですら Lisp だという人もいるくらいです。 数ある Lisp の中でなぜわたしは Common Lisp を使うのか、まずその理由から始めます。

3.1 CL is not "pure" - it is "general"

最初はこれです。

programming とは文章書きのようなものと考えて良いのではないか。 良い program とは読者 (人) を想定し、無駄なく簡潔に、 しかし書き手のそのときの意図が伝わってくるような、表現力豊かなものであるべきでしょう。 そのためには、豊富な (あるいは雑多なといっても良い) 語彙や表現手段を知り、 それらを文脈に応じて使いこなせる必要があろう。つまり型にハマってはいけない。

general な言語というものは同じことを言うのにも色々な表現ができる。これは自然言語も同じ。 例えば Common Lisp を例にとると、構造をもったデータ型を決めるのにも、

など色々ある。計算機にとっては同じ computable object でも、 など様々な表現が使いわけられる。計算機にとっては同じ手続きにすぎない、 などもまた使いわけられる。 を使いわけるのもこれまたあたりまえ。 文脈に応じて、どういった語彙や表現法を使えば良いかが決まる。 そしてそれを判断するのは人間 (programmer) である。 ようするに、

3.2 I don't like languages whose designers know what is best for me.

自分の使う言語が、 関数型 (whatever) programming に向かない、というのは困るが 関数型 (whatever) programming に しか 向かない、というのはもっと困る。

ちなみに designers know what is best for me という点からみれば script 言語系はすべてこれ。 世にある general な言語仕様から自分の感性にあうものだけを pick up したオレ言語。 つまりは、

3.3 "let's discard all the community effort and start over from scratch because we're smarter than everybody else" thing

先人の知恵よりも自分のアイディアのほうが秀れている。 ものを学ぶ前に自分で発明してしまう。 言語 設計 ということがされたことはなく、 その証拠に言語仕様もなければ標準もなく実装だけがある。 オレ が決めればそれが即ち仕様である。 こういう プチ独裁 scripters に席巻されるくらいなら、

3.4 Let's just hope that all the world is run by Bill Gates before the Perl hackers can destroy it.

いっそのこと、さっさと ビル・ゲイツ に世界征服してもらいたい。

結局 language が general になるためには、 標準化の動きがあり、ANSI, JIS 化される、 という過程を経たときに限られるのではないか。

各人各様の意見要求を遍く理解した上で標準化する、ということは政治だと見てよい。 「良い政治とはより賢く妥協することだ」 とすれば、妥協の産物である 委員会言語 こそが使うに足る non-pure で general な language ではないか。 わたしはそれを Common Lisp に見る。

なお、ここで委員会と言ったのは、言語仕様を決めるのに直接民主主義のようなやり方は好ましいとは思わない。 それは R6RS を見てもよくわかる。 やはり委員会が必要だろう。

ちなみに 「委員会言語」 とは昔読んだ和田先生のエッセイから拝借。

4 より S/N 比の高い Lisp 情報を得るために

ここでちょっと脱線して、上のようなことを考えてみます。

Lisp というのは、話題になる割には (残念ながら) 本当に使っている人は少ない。 本当に使っている とは 仕事で使っている という意味。 つまり、

4.1 If you want to know why Lisp doesn't win around you, find a mirror.

この言葉こそふさわしい人達がたくさんいる、ということ。 自然に耳に入ってくる Lisp に関する話題は、(残念ながら) 眉に唾つけて聞く必要がありますが、 「どういった人達が Lisp を使っていないのか」 ということを押さえておくと signal/noise の noise をある程度落とすことができる。 Lisp を使ってない人の一番の典型は、

4.2 I love Lisp but...

まずはこの手合です。 Lisp が好きなんですけど、Lisp を使いたいんですけど… 「ですけど」のあとに続くのはもちろん「自分は使ってません」というフレーズ。 そこで 言訳 が必要になるが、 よく聞く一番の理由が「上司が認めてくれなくて」というものです。

「上司が認めてくれなくて」使えない程度のモチベーションなら別に使ってもらわなくて結構。 しかしこういう人には鬱屈がたまりやすいようで、 「初心者用の解説がない」、「処理系が有償」、「ライブラリが貧弱」 といった Lisp 攻撃に転じることすらある。(comp.lang.Lisp で何度もあった)。 さすがに日本は民度が高いのか、こういう攻撃はあまり見ない。 ただし日本の場合これと非常に近い態度の一つが、

4.3 Lisp を使わないやつに限って Lisp について語りたがる

この傾向は残念なことに Lisp だけ。C や Java でのこういう例を少なくともわたしは知らない。 なのでネットで Lisp についての情報を得るのはとても危い。 それと Lisp を知っている、という人の言葉も軽々しく信じてはいけない。 とくにオレも昔やってた、的な人達。

4.4 自称 Lisper に限って Lisp のことは何も知らない

昔やってた、ってことは「今はやってない」ということ。 だまされないようにしましょう。

結論として一般に 「リスプ、リスプ」 という人に Lisp の話を聞いてもあまりためにならない。 Lisper は自分が Lisp を使っていることをあまり大きな声では言わない。

Lisp の情報を得たいのなら、ちゃんと本を読みましょう。

Lisp についての良い本はいっぱいある。 Peter Norvig は、Paradigms of AI Programming の序章で、その参考図書に初学者用として 5冊 も挙げている。 CLtL2 も外せない良書ですが、 日本は世界に冠たる Lisp 王国であり、日本語で読める本がいくつもある。 随筆風のソフトウェア千夜一夜、ソフトウェア考現学 なども面白い。 80年代のbitもお勧め。out of print のものも多いが図書館など行けば読めるはず。

5 CL 批判について

Common Lisp の話題に戻ります。

Common Lisp には良くある批判というのがあります。 (Frequently Attacked Questions とでも言うんでしょうか) そのうちわたしが代表的だと思うものをいくつかピックアップして、 コメントしてみたいと思います。

5.1 What's wrong with complicated? If your language is complicated, it can handle more complicated problems simply. If it is simple, you must then build more structure and complication into your application in order to handle the same level of complexity in your problem set.

まず、仕様が巨大だ、ということ。 このことがどうして批判になるのかがわからない。

弊社の C 開発者曰く、今まで何度 hash table を書いたか知れない。

権利関係を考えるとそう単純ではない。 NTT の予算で組んだものが KDDI に使えるか。 適切なものが拾ってこられるか、という問題と、よしんば拾ってこれたとして、 顧客を No warranty の free ware と心中させるわけにはいかない。 そこで自分の責任で保守することになるが、そうなると、 software life cycle を考えたときに、scratch から書くのとどれほどの差があるのか。

library に関して言うと、 CL へのアンチテーゼとして、言語仕様を小さく、 余計? なものは library として分ける、という意見がある。 二つの面でわからない。

この疑問に答えてくれた人は今までいない。

ここで司馬遼太郎の短かいエッセイに「日本語について」というのがあるのでとりあげる。

エッセイによれば日本語とモンゴル語は姉妹言語とでも言うべきとても良く似た言語。 両者とも膠着語といって、助詞で単語をはりつけるように文を組み立てていく。

ただ一つ大きく異る点がある。

日本語は1000年以上前に漢字を導入し、熟語を語彙として国語に組み込んでいくという作業が永々となされてきた。 一方、モンゴル語は古の大和言葉のままに止まっている。

例えばモンゴル語には鉛筆に相当する語彙がない、どうしても言いたければ なまりのふで というよりない。 もちろん文房具屋にいって「なまりのふでをください」と言ったところで通じないのは日本でもモンゴルでも同じ。 そこで、中国境に近い人達は中国語から、ロシア境に近い人達はロシア語から単語を輸入。 結局、任意のモンゴル人に通じる 鉛筆 に相当する語彙というものはないまま。

閑話休題。

library とはまさにこの「外来語彙」のことではないのか。 言語仕様を小さく (大和言葉のまま) にして、新たに必要となった語彙は外から つけたしてやれば良い、という考え。 ところが、これでは言語は存続しえない、と司馬さんは言う。 モンゴル語は結局その (美しい) 文字までロシア語化させてしまった。 エッセイの最後では、日本においてやたらに漢字制限したがる風潮に警告を与えています。

Lisp には macro と呼ばれる、既存の言語に新たな語彙を組み込んでいく仕組みが用意されている。 AMOP を読んでわかることは CLOS というものが macro で拡張された新たな言語、 つまりベースとなる CL の仕様とは独立のものであることがわかる。 それでも ANSI は CLOS を仕様に組み入れ、その語彙をもって condition system などを定義している。 これこそが言語を成熟させていく確かな方法ではないのか。

ちなみに、小さな言語仕様にlibrary、という代表選手は またやり玉でもうしわけないが、script 言語たち、 このコミュニティの人が自分の名前をひらがなで書いたり ハンドルを使いたがる傾向が、先の司馬の話と重なっていて面白い。

5.2 I think many of the "let's change things" people don't have a good appreciation of the importance of maturity.

次の批判は「古い」というもの。 これもわからない。 自分の話している国語を、古いからという理由で批判している人というのは見たことがない。

ただ ANSI 制定以来仕様が止まっているのは確か。 ドイツ語の正書法も変わるくらいなんだから (1998 〜 2005 移行期間) 、 プログラミング言語仕様にもう少し改訂があっても良いという意見は妥当だろう。 MOP が standard になることは良いと思うが、これは難しいだろう。 金と時間がかかりすぎる。CLOS が仕様化されていることで満足すべきではないか。 一方 multi processing の際の special 変数がどう扱われるべきか、 environment や object oriented な stream (gray-stream & simple-stream) などは仕様にあるべきだと感じます。 ちなみに、 multi processing については Lisp machine Lisp が defacto standard のようになっているのと、environment や simple-stream については open source を提示した上で、各実装が実験的に取り入れることのできる形の仕様提案がなされている。

X3J13 という ANSI 分科会に一時期所属していた時期もあったが、 その当時参加者が最低の4人しか集らず、何ができるものでもなかった。 その後その4人も欠けるようになったため、現在は機能していないはず。 標準化にはお金がかかる。お金をうごかすには、 世の中が標準化というものを認めてくれないことにはどうしようもないが、 その前に自分達がまず標準というものを大切にしていくことが大事なのではないか。 community の基盤をしっかりさせておく。

5.3 Imagine a programming language that is not a weapon in someone else's marketing war, but is stable and has proven useful to actual programmers over a whole decade! Is it not amazing?

言語仕様が硬直するのは困るが、しかし仕様とは本来険固なものであるべきだろう。

PHP は programmer の仕事を切らさないために版改変をしているのではないかとまで疑えるし、 Java (framework) にもそういう面があるというはなしを聞いた覚えがある。 上位互換を壊すことによる市場戦略というものがあることは事実だろう。 Common Lisp はそういったものから一番遠いところにいる。

5.4 Common Lisp is not a "free" language in that it takes no effort to learn. Common Lisp is not a "free" language in that you can as easily discard it. Common Lisp is not a "free" language in that you will be unchanged by it. Common Lisp is not an investment-free language, but neither it is profit-free.

今時フリーでない言語処理系なんて、という批判もまた多い。 しかし、批判の前に、 どうしてそういう商売が成り立つのか考えるべきではないか?

わたしはこの10年間、Allegro CL license fee を高いと思ったことはないし、高いと思ったら交渉している。 払っただけの (以上の?) サポートは要求しているし、相手もこちらの要求には高い優先度をあたえてくれている。 お金を払わなければ何の優先度も得られないのはあたりまえ。つまり、

5.5 Free Software is only free if your time is worth nothing.

6 Scheme について

期待して来てくれた人も多いと思うので Scheme についてふれておきます ;)

6.1 Scheme isn't a member of the Lisp family, but rather of the Algol Family.

わたしを含め多くは Scheme を Lisp だとは思ってない。 Algol である。 RxRS を一瞥すれば明らか。 R4RSでは、その表紙に、

と記載されている。Algol 60 では、 R5RS では やっと contributor の一人が亡くなってくれたおかげで、 ここまでしてついに Algol になったのが Scheme.

Algol だと思えば全ての Scheme 批判は意味がなくなるが、そもそも、

6.2 The only people who are interested in Scheme vs Common Lisp are those who are interested in Scheme. Nobody else could possibly care.

CL と Scheme を比べることは りんごとみかんを比べるようなもの。 両者はそれぞれが特徴と利点をもったまったく違うもの。

ところが、両者それぞれの特徴と利点を混同し、 りんごをみかんに、(あるいはみかんをりんごにか) しようとした愚かな例が R6RS. Robert Hieb に霊があったら墓が動いたんではないか?

ようするに Lisp のめがねで Scheme を語る、 Scheme のめがねで Lisp を語ることは不毛。

では、お前はどうなんだ、と言われるかもしれないが、

 男について語るには女について語ればいい
という言葉もあるわけで、そういう意味では 「Lisp について語るには Scheme について語ればいい」 ということが言えるかもしれない。 両者の差を浮き彫りにしておくのは悪いことではないだろう。

6.3 Scheme is all wrong. Making nil different from false is nuts, and letting forms have an unspecified value is also just plain wrong.

空リストが偽を表さない時点でもう Lisp ではない。 もとはそうではなかった。 r4 から変わったと記憶しているが、このあたりから Scheme コミュニティ というものがロクでもないものになっていったように感じる。

6.4 Consider the names people would have if they had to have globally unique names. That is what a single namespace does to programmers.

single namespace を受け入れる、ということは symbol を捨てる、ということに等しい。 symbol とは package あってのものであるが、 single namespace を貫くかぎり package というものは持てない。 なぜなら package のための namespace というものが与えられないので。 したがって、

6.5 Scheme symbols, at least in a language-neutral discussion, as "keywords" and not really as "symbols".

ところが symbol がないと実質 macro が書けない。名前の衝突が防げないから。 おそらくここで、Scheme の人は、 自分の登ってきた梯子を蹴落としてしまったことに気づいたにちがいない。 (Wittgenstein が言ったような意味ではなく。) そこで苦しまぎれに wheel reinvention したものが、R5RS の hygienic macro. ちなみに Scheme は Algol である、という意識さえあれば macro など無用の長物だと思うのだが…

6.6 "Hygienic" vs "Non-hygienic": In simpler terms, it is an us-vs-them, good-vs-evil thing.

hygienic とはようするに差別用語。 差別の対象は、あきらかに CL macro。 自ら梯子を蹴落としてしまったが、後に引けない悔しさ、というのがこの名称に表れている。 ちなみに Scheme にはこの手の差別用語が多い。 Properly tail-recursive のようなものも同じ。 CL は CL なりに tail call を 適切に 処理している。 Scheme のやりかただけが proper なわけではない。

最後に R6RS にとどめをさしておきたい。

6.7 About the only thing SGML got right was being case-insensitive by default, but the fools who `designed' XML were blinded by the lOvely naming staNdaRds YoU Have tO UsE in lanGuaGeS without convEnIent inter-woRd seParaTors.

R6RS の一番阿呆な仕様は (default) case sensitive にしてしまったことだろう。 Lisp は大昔から case sensitive と case insensitive を区別して使うことができる唯一の言語である。 (eq 'a 'A) は T を返すが、(eq 'a '|a|) は NIL を返す。 これほど気の利いた仕様を持つ言語が他にあるか??

しかしながら悲しいことに Common Lisp community にすら、これを破壊しようとする連中がいる。 Allegro の modern mode といわれるものがそれ。 あなたが多少なりとも Lisp community の一員だという自覚があるのなら Allegro の modern mode を使うのは 絶対に やめましょう。Franz は Allegro free express edition を、彼等が modern mode と呼ぶ去勢手術され た CL として出している。あなたが express の ユーザなら、なぜ (eq 'a 'A) が nil を返すのか、しつこく support_ at_ franz_ dot_com にメイルして責めましょう。

念押ししておくが、 modern mode を喜ぶユーザがいるから必要だ、というのは理由になっていない。 どこの国にも偽金をありがたがる輩というのはいるものである。

7 課題

最後に自分なりの課題をあげておきます。

Performance is the last refuge of the miserable programmer.
という言葉がありますが、 それでも遅いプログラムというのは相手にされません。 Lisp で書いた program を Lisp なんだから遅いのはしかたないね、などと言っ てるようでは永遠に Lisp など使わせてもらえない。

CL の SMP 対応というのはきっちりやるのはなかなか骨が折れるようですが、 これからは multi core を使いきれるようなプログラムを書いていく必要があると感じています。

LAPACK (Linear Algebra PACKage) の CL 化というのもテーマとして持っています。 LAPACK が使う BLAS (Basic Linear Algebra Subprograms) には F77 で書かれてる実装がありますが、 これを cl-f2cl (Common Lisp package to convert Fortran 77 source code to Common Lisp) を使って CL ソースに落とし、各種プラットフォームで fortran 並みの速度のものを走らせたい。 今のところ cl-f2cl に問題があってうまくいってないが解決したいと思っている。 もっとも BLAS には Intel の Math Kernel Library という実装があり chip 用に超高速チューニングされていて Intel chip を使う限りはマトモには勝てない。

Concurrent programming 環境として、 CL の上に Guarded Horn Clauses のようなプログラミング環境がつくれると素敵だな、と思います。

stableness が大切なのは改めて言うまでもないこと。

あとわたしからのメッセージとして、「Lisp Programmer などと言う職業は成り立たない」というのを強調しておきたい。 顧客がいて、要求分析、システム設計、詳細設計、 プログラマがいてマネージャがいる、そういった中での Lisp プログラマと いうものは、成り立たないと思います。 Lisp を使うというのは、顧客要求にトータルで見て最小コストで答えるための手段であって、 顧客が見えてない Lisper というのは (そういうものがいたとすれば) 救い難い。 Lisp と C や Java との一番大きな差はこの点にあるのかと思います。

最後に、「お金は大事」です。 Lispで (Scheme でも ML でも何でも結構) お金をかせぎましょう。 Java で給料もらってますが、趣味で Scheme 使ってます、なんてのは一番聞きたくない。

Author: KURODA Hisao <kuroda_at_msi_dot_co_dot_jp>

Date: 2009/03/13 11:05:16 AM