LispがS式に拘る理由は、くろださんのおっしゃる通りマクロだと思いますよ。

kono@ie.u-ryukyu.ac.jp (Shinji KONO) writes:

> > CL の macro が CL の macro でいられるのはS式のおかげでしょうに。
> 
> 高階関数っていうアプローチもあって、マクロとどっちが良いかっ
> て言うと、理論的には高階関数の方が良いみたいですね。「理論的
> には」です。MLer は、きっと、Common Lisp で出来ることは全て
> MLで出来ると言うだろうな。

高階関数でマクロみたいに構文拡張しようと思うと、Haskellのようなlazyな
言語じゃないと難しいですね。たとえば、

(my-case expression
  (constant1 form1...)
  (constant2 form2...) ...)

みたいに、評価しない式があるような構文はstrictな関数としては書けないで
しょう。λ式でくくってやるとかしないと。

また、局所変数を宣言するような構文拡張(Lispのletみたいなもの)はHaskell
やMLじゃ書けないでしょう。

(だからMetaMLとかTemplate Haskellなんてのが研究されてるわけで…
んで、結局S式使ったマクロと良く似てるんだな、これが。
まあ、静的な型という大きな違いがあるけど。)

> > > 「Interpreter を重視していれば、そうはならなかった」
> > 消えちゃってたんじゃないでしょうか。言語自身が。
> 
> いや、まぁ、Scheme も残っているっちゃ残っているわけだし。Perl
> も Emacs lisp も残っているわけだし。消えるってことはなかった
> と思うんだけど... Common Lisp って名前自体が「他のは許さん!」
> みたいな強圧的な所があって、それが少し良くなかったかなぁ。

「用途を(教育用とかプロトタイピング専用とかに)限定しない」ためにはネィ
ティブコードコンパイラが必須だとくろださんは主張しているのだと思います。

「教育用」「プロトタイピング用」「スクリプト用」というのは、効率より他
に重視している点があるといっているわけですが、裏返すと「非効率だけどこ
ういう用途なら使える」という言い訳に使われている面がなきにしもあらず。

そういう「ニッチ」に自らを封じ込めた特殊用途の言語としてでなく、汎用の
言語であり続けるためには、インタプリタじゃダメだと。(耳が痛い。)

また、河野さんは、「Common Lispはインタプリタを否定している」と思って
いる節があるけど、これは誤解じゃないかな。Common Lispは別にインタプリ
タに反対してるわけではなくて、コンパイラの邪魔しないように気を使ってる
だけですよね。具体的には、
    ・コンパイラとインタプリタで意味が変わらない
    ・高性能なコンパイラが作りやすい
という仕様にしてある。たいていの処理系でインタプリタも付いてますよ。

さらに言うと「(Common Lispと違って)Schemeはインタプリタを重視している」
と思ってる節があるけど、これも誤解では。

In <3990434news.pl@rananim.ie.u-ryukyu.ac.jp> kono@ie.u-ryukyu.ac.jp (Shinji KONO) writes:

> でも、僕に取ってのLISPというと、 シンプルな構文とシンプルな
> 操作意味論を持っていて、その上に、マクロでシンタックスシュガ
> ーをかけるっていうものだっていう偏見があるんだよね。それで、
> 十分にコンパイラが最適化をかけられる筈だと言う感じで。
> 
> そういう意味で、Common Lisp は、僕に取ってはLISPっぽくないLisp
> ってわけです。

「LISPっぽいLisp(系言語)」としてSchemeを想定しているのかと思いますが…

そもそも「マクロ」っていうのはインタプリタ重視じゃなくてコンパイラ重視
であることの表れなんですよ。マクロってインタプリタだと遅くなるじゃない
ですか。

インタプリタを重視すると、構文の拡張は「特殊形式」(FEXPR)に基づくもの
にしたほうが有利です。まあ、一種のリフレクションですね。そして、ユーザ
が拡張した構文は基本的にコンパイルできません。

たとえば、
  (cond (expr1 form) ...)
  を評価する時、「exprを評価して、もし真ならformを評価して…」という評価
  ルーチンを書くのがインタプリタベースの(古しえの)処理系。こういう評価ルー
  チンをユーザが書いて、たとえばcase構文を作ることもできるけど、それはコ
  ンパイルできない。

  「(if expr1 (begin form) (cond ...))に変換する」というルールだけ記述
  して、変換してからあらためて処理するのがマクロベースのモダンな処理系。
  インタプリト時には遅くなるけど、コンパイルは楽。

あと、型宣言はSchemeの標準規格に入っていないけど、そういう拡張を禁止し
ていないし、型宣言を使って最適化する処理系もあります。

> だけど、必ず「そういう所を極限まで使うプログラム」ってのを書
> くのがいてさ... C++ のTemplate マニアと、Common Lisp のマク
> ロマニアと、なんか似てない? そんな感じなんだけど... 

CLのマクロは単にS式→S式へ変換する普通のプログラムなので、Lispプログラ
マなら割と読みやすいですね。C/C++のマクロ, TemplateやSchemeの
extend-syntaxと違って、マクロ専用の全く別の文法を導入したりはしていない。

                                前田敦司