話題がずれているので、subject と group、followup-to をいじ
りました。
Shinji KONO wrote:
> In article <cgsd8i$kok$1...@newsl.dti.ne.jp>, "Anonymous Buddha"
> <gob...@yahoo.co.jp> writes
>> 人工知能研究の対象としてはそんなに盛んではなくなったものの、1言語・
>> ツールとしてはまだまだバリバリ使われている、と言った感じでしょうか?
>
> ニューラル・ネットワークやロボットの方だと、LISPははっきり向
> いていないので、使っている人はいないでしょうね。 C とか使っ
> ていることが多いと思う。
>
> けど、言語処理となると、まだLISPを使っているところが多いんじ
> ゃないかな。資産が結構あるし。適当なエンジン + LISP風スクリ
> プトってのもあるけど。そういうものを作ろうと思うと、LISPが参
> 考になるってのはありますね。
ちょうど似たような話を会社内でもしてるんだけれど、自分が LISP をいじ
るのは、何のプログラムを作るかより、どういうプログラミング・プロセス
を採るかで決めているような。
探索的手法というかヒューリスティックにプログラミングをする際は、LISP
や Smalltalk が楽で、その中でも興味の焦点がアルゴリズム寄りの場合は
LISP が楽。
そんな判断基準のような気がするのです。
--
「十分間で決断し、短い理由を添えよ」
A.I.Soft, Inc. CS・品質推進課 成田隆興
In article <ch6ihv$1852$1...@newsnnrp00.cwidc.net>, Narita Takaoki <tak...@aisoft.co.jp> writes
> 探索的手法というかヒューリスティックにプログラミングをする際は、LISP
> や Smalltalk が楽で、その中でも興味の焦点がアルゴリズム寄りの場合は
> LISP が楽。
欠点としては、GCとか参照カウントが入って来るので、計算量がい
まいち正確に見積もれない所なんですよね。なので、計算重視(単
純ループが多い) みたいなものだと、ちょっと困る。あとリアルタ
イム関係も。
アルゴリズム寄りってのが、
とにかく、論理的には正しく動く
ってことなら、確かに、LISPが最速かも知れない。
少しずれるけど、可変長データ構造を柔軟に(いいかげんに、型な
しで) 大域的に定義できるってのは便利なんですよね。
---
Shinji KONO @ Information Engineering, University of the Ryukyus
河野真治 @ 琉球大学工学部情報工学科
> ニューラル・ネットワークやロボットの方だと、LISPははっきり向
> いていないので、使っている人はいないでしょうね。 C とか使っ
> ていることが多いと思う。
ロボットだといるんじゃないですか。
EusLispとか。御大Rodney BrooksのL言語(CommonLisp for Embedded Systems)
とか。
> 欠点としては、GCとか参照カウントが入って来るので、計算量がい
> まいち正確に見積もれない所なんですよね。なので、計算重視(単
> 純ループが多い) みたいなものだと、ちょっと困る。あとリアルタ
> イム関係も。
うーむ。malloc/freeだと正確に見積もれるんでしょうか。
前田敦司
> 欠点としては、GCとか参照カウントが入って来るので、計算量がい
> まいち正確に見積もれない所なんですよね。
GC が入る → 計算量が正確に見積れない、というのが良くわかりません。
あと、参照カウントって何でしょう?
> 計算重視(単純ループが多い) みたいなものだと、ちょっと困る。
どうして困るのか良くわからないんですが…
> あとリアルタイム関係も。
real time gc は euslisp に載ってたと思いました。
> GC が入る → 計算量が正確に見積れない、というのが良くわかりません。
> あと、参照カウントって何でしょう?
fj.comp.lang.implementationほかでこないだ議論したとこなんです
が、河野さんは
○普通のGCによる停止時間は不定長であり上限を設けられない。(大嘘)
○上記の問題がない(少い)のは参照カウント法のGCだけである。(大嘘)
という二つの迷信を信じてらっしゃるようで、そのとき我々が説得した
のですがどうも信用して頂けないようです。
> real time gc は euslisp に載ってたと思いました。
どっかにペーパーありますか? 探したけど分からなかった。 久野
> > real time gc は euslisp に載ってたと思いました。
> どっかにペーパーありますか? 探したけど分からなかった。 久野
;; わたしの記憶が確かなら
ここ↓で言われている a multi-threaded Lisp system for robot control
というのが euslisp のことだと思います。
http://ryujin.kuis.kyoto-u.ac.jp/~yuasa/ilc2002/
In article <ch74b2$u...@utogw.gssm.otsuka.tsukuba.ac.jp>, ku...@gssm.otsuka.tsukuba.ac.jp writes
> ○普通のGCによる停止時間は不定長であり上限を設けられない。(大嘘)
> ○上記の問題がない(少い)のは参照カウント法のGCだけである。(大嘘)
> という二つの迷信を信じてらっしゃるようで、そのとき我々が説得した
> のですがどうも信用して頂けないようです。
これはリアルタイムの話ですよね。参照カウントを使うと、停止時
間の予測は難しいというのと、参照カウントを使わないリアルタイ
ムGCの実装は少ないみたいな「迷信」は信じてます。
計算量の話だと、naive append みたいなものでもゴミが結構でます
よね。これを再利用しないとすると、空間計算量は当然大きくなります。
(あたりまえ...) 再利用するためには、当然だけど、時間計算量は
かかる。これも当り前。
久野さんの主張が GC の手法の選択は問題の計算量に影響を与えな
いってものじゃないですよね。与えられた問題に対して時間空間計
算量に影響を与えないGCの手法が必ずあるってのは、あるかも知れ
ないけど、あらゆる問題に対して有効なGCの手法があるっていうの
は、僕は信じてないです。
> これはリアルタイムの話ですよね。参照カウントを使うと、停止時
> 間の予測は難しいというのと、参照カウントを使わないリアルタイ
> ムGCの実装は少ないみたいな「迷信」は信じてます。
少いなんて防御しちゃって ^_^;; 数だけ数えたらstop and collect
な実装が一番多いに決まってるじゃないですか。でもリアルタイム化だっ
て別にやるだけでしょ? すこし議論しましょうか。
ごく普通のマークスイープGCの行う動作を、1セル割り当てるごとに
「一定量」ずつ行うことができないと思う根拠は何かありますか?
fj.comp.lang.implementationに振りますね。 久野
> ;; わたしの記憶が確かなら
> ここ↓で言われている a multi-threaded Lisp system for robot control
> というのが euslisp のことだと思います。
えー、だってこのペーパーは湯浅先生がeulispに自分のGCを入れて
realtime化してみました、ってな内容なんでしょ? それをもって
「eulispはrealtime GCを持っている」とは言えないような。
あれ、そういう意味じゃなかったのかな… 久野
ko...@ie.u-ryukyu.ac.jp (Shinji KONO) writes:
> 久野さんの主張が GC の手法の選択は問題の計算量に影響を与えな
> いってものじゃないですよね。与えられた問題に対して時間空間計
> 算量に影響を与えないGCの手法が必ずあるってのは、あるかも知れ
> ないけど、あらゆる問題に対して有効なGCの手法があるっていうの
> は、僕は信じてないです。
まさか動的「割り付け」を使わない場合とGCを比べてるんじゃないですよね。
手動で「解放」するかGCを使うかで計算量(定数倍)が変わるという主張ですよ
ね? (オーダーは普通かわりませんよね?)
うーん、そりゃ変わるでしょうね。速くなることも遅くなることもあるでしょう。
(あんまり速くない保守的GCとmalloc/freeを比べた
http://citeseer.ist.psu.edu/zorn92measured.html でも勝ったり負けたり。)
でも、そもそも、割り付け/手動解放のコストを見積もるのもかなり難しいと
思うんだが… まさかmallocやfreeがO(1)とか思ってませんよね。
前田敦司
Conservative GCが malloc/free に負けないってな話はそういえば、
あったなぁ。
In article <m3wtzc8...@nospam.maedapc.cc.tsukuba.ac.jp>, MAEDA Atusi <maeda...@ialab.is.tsukuba.ac.jp> writes
> まさか動的「割り付け」を使わない場合とGCを比べてるんじゃないですよね。
> 手動で「解放」するかGCを使うかで計算量(定数倍)が変わるという主張ですよ
> ね? (オーダーは普通かわりませんよね?)
ううむ... 破壊的append と非破壊的appendではオーダは変わりますよね。
でさ、
> でも、そもそも、割り付け/手動解放のコストを見積もるのもかなり難しいと
> 思うんだが… まさかmallocやfreeがO(1)とか思ってませんよね。
free を O(1) にするには、memory pool みたいなのを使うと可能
です。非破壊append bench mark を別プロセスでやって GC しない
で抜けて来るみたいな感じ。それが一般的なGCの仮定に反する(自
由に参照をコピーできる) のはその通りです。で、そういうことす
ると GC を持っているシステムでは、まずいってな話でしたよね。
二乗でゴミを吐くプログラムなんてダメダメなのは、その通りなん
だけど、線形でゴミを出すのは良くありますよね。というか、これ
までの話だと、むしろ推奨されている。で、そうやって生成したゴ
ミを回収するコストが、ゴミの量に比例するかって言うと、それは
アルゴリズムによります。
なんか避ける方法あるのかなぁ。
> free を O(1) にするには、memory pool みたいなのを使うと可能
> です。
そりゃフリーリストの先頭にくっつければO(1)つまり定数時間になり
ますが、alloc するときどうするの。ヒープを端から取って使い切る前
に計算終了するんだったらそもそも動的alloc不要だよね。フリーリス
トから取ろうとしたとたんに、O(1)じゃなくなるでしょ、適合するもの
を探さなければならないから。全部同じサイズ? それはずるいな ^_^;
> 非破壊append bench mark を別プロセスでやって GC しない
> で抜けて来るみたいな感じ。それが一般的なGCの仮定に反する(自
> 由に参照をコピーできる) のはその通りです。で、そういうことす
> ると GC を持っているシステムでは、まずいってな話でしたよね。
GCがなくてすむ例でGCが遅いとかいうのはフェアじゃないね。GCが
ないとメモリが足りない例でGCと手動と比べてよ。
> 二乗でゴミを吐くプログラムなんてダメダメなのは、その通りなん
> だけど、線形でゴミを出すのは良くありますよね。というか、これ
> までの話だと、むしろ推奨されている。で、そうやって生成したゴ
> ミを回収するコストが、ゴミの量に比例するかって言うと、それは
> アルゴリズムによります。
比例する=それぞれのゴミについて(償却)定数時間、ね。では定数時
間のアルゴリズムを挙げてみてください。
「よる」っていうのだからあるんでしょ? 久野
> このペーパーは湯浅先生がeulispに自分のGCを入れて
> realtime化してみました、ってな内容なんでしょ?
ええ、そう理解してます。
> それをもって「eulispはrealtime GCを持っている」とは言えないような。
何をもったら言えるんですか?
In article <ch8bqc$28...@utogw.gssm.otsuka.tsukuba.ac.jp>, ku...@gssm.otsuka.tsukuba.ac.jp writes
> 久野です。グループがもはやlispじゃないと思うが計算量だとどこか…
あんまり移るのも良くないと思うので...
> GCがなくてすむ例でGCが遅いとかいうのはフェアじゃないね。GCが
> ないとメモリが足りない例でGCと手動と比べてよ。
GC がないとメモリが足りない例っていうのは、unbound っていう意味
なわけなんだけど...
でもさぁ、メモリ使用量がunboundなアプリケーションって実は、
インタプリタ的なものしかないんじゃないかなぁ。Conservative GC
とかでも対象は awk interpreter だったりしますよね。
bound されてたら GC しない方が良いっていう論法なら、かなり
のアプリケーションはGC抜きで良いってことですよね。そうなのか。
(Web browser の計算量はとか考えている人いるんだろうか?)
> 比例する=それぞれのゴミについて(償却)定数時間、ね。では定数時
> 間のアルゴリズムを挙げてみてください。
> 「よる」っていうのだからあるんでしょ? 久野
mark and sweep で生きているセルが定数の場合なんかそうですね。
逆に生きているセルが増加するような場合は困るんだよな。でも、
そういう場合は、それほど珍しくないです。そういう場合は、ディ
スクに書き出すのかな? LISP だと、(eval (list 'defun ....))
とかするんだろうか?
> ううむ... 破壊的append と非破壊的appendではオーダは変わりますよね。
オーダーは同じだと思うなあ。 Lispで言えば (append a b) と (nconc a b)
ですよね。どっちも O(length(a))だと思う。
> free を O(1) にするには、memory pool みたいなのを使うと可能
> です。非破壊append bench mark を別プロセスでやって GC しない
> で抜けて来るみたいな感じ。それが一般的なGCの仮定に反する(自
> 由に参照をコピーできる) のはその通りです。で、そういうことす
> ると GC を持っているシステムでは、まずいってな話でしたよね。
なるほど。RTSJ (Real-time Specification for Java)のRegionみたいに一括
解放するわけね。dangling pointerのチェックもしなくて良いなら、確かに最
速ですね。
しかしですね。以下の条件が満たされるならオーダーは変わんないですよ。
・割り付けた領域には、少なくとも一回データが書き込まれる(初期化でも可)
・ヒープサイズは生きているデータの量に比例して増加させてよい
・GCのルート集合の大きさは、高々生きているデータの量に比例する程度
この条件だと、「Nバイト割り付けて解放する」サイクル全体のコストは、GC
使おうと使うまいとO(N)になりますよね。
実際の話、一括解放でよいプログラムの場合、ある期間に割り付けられたオブ
ジェクトが全部ゴミになるわけですよね。これは、現在よく使われているコピー
式の世代別GC がうまくアジャストできれば、全くコピーしないでGCが終る可
能性があります。この場合、ほとんどコストは変わらないでしょう。コピーGCっ
て結局「dangling pointerにならないようにコピー + 一括解放」ですから。
そう都合良くサイズが合わないで、何回かコピーしちゃったとしても、オーダー
は変わらない。たかだか定数倍。
> 二乗でゴミを吐くプログラムなんてダメダメなのは、その通りなん
> だけど、線形でゴミを出すのは良くありますよね。というか、これ
> までの話だと、むしろ推奨されている。で、そうやって生成したゴ
> ミを回収するコストが、ゴミの量に比例するかって言うと、それは
> アルゴリズムによります。
上のとおりヒープを増加させて良いなら、ゴミの量というか割り付けた量に比
例するコストで回収できます。つまり、1バイトあたりの割り付け+回収のコ
ストは定数オーダー。
前田敦司
> > それをもって「eulispはrealtime GCを持っている」とは言えないような。
>
> 何をもったら言えるんですか?
標準配布のeulispにrealtime GCがついていれば。というかそういう
意味に最初受け取りましたもので。「eulispにrealtime GCを組み込ん
だ例がある」なら全然文句ないんですが。
まあ大したことではないかも。 久野
P.S. もしかして湯浅GCがeulispと一緒に配布されているとか既に組み
込まれているということなら全然OKです。その場合は突っ込んで
済みません。
> GC がないとメモリが足りない例っていうのは、unbound っていう意味
> なわけなんだけど...
違うよ! 所要合計がヒープ量の倍で、でもワーキングセットは収まる
とかそういう意味ですが。
> でもさぁ、メモリ使用量がunboundなアプリケーションって実は、
> インタプリタ的なものしかないんじゃないかなぁ。Conservative GC
> とかでも対象は awk interpreter だったりしますよね。
それも大嘘だよ…でもとにかくunboundの話じゃないので。
> 生きているセルが定数の場合なんかそうですね。
それで結構ですよ。
> mark and sweep で
ちょっと! markするのもsweepするのもヒープサイズに比例するじゃ
ないですか。それはO(1)ではなくO(N)です。
それにGCはそういうもんで、私が河野さんに質問していたのは自前で
alloc/freeするならO(1)で済むという方の具体例。セルの総量は平均定
数、でもランダムに割り付けと開放が行われる。で、どうやってヒープ
サイズに関わらずに定数時間でalloc/freeするかというと。
うーん、その場合は… 久野
P.S. もしかしてセルは全部2のべきサイズでそのサイズ種類数だけリス
トを作るってやつかな。無駄が最大50%だけどそれなら定数かも。
前田さんどうしますか。
> P.S. もしかしてセルは全部2のべきサイズでそのサイズ種類数だけリス
> トを作るってやつかな。無駄が最大50%だけどそれなら定数かも。
> 前田さんどうしますか。
河野さんは、ポインタをずらすだけで割り付けて、解放する時は全体を一括解
放する(ポインタを初期値に戻す)ようなアロケータを考えてるのでは。
memory_pool *make_memory_pool(size_t bytes);
void *pool_allocate(memory_pool *, size_t bytes);
void pool_reset(memory_pool *);
typedef struct memory_pool_impl {
size_t size;
void *base;
size_t used;
} memory_pool;
みたいな感じ。
もちろん、malloc/freeほどgeneralではないですが、これで済むような応用な
ら(割り付けた部分を初期化しないとすれば)pool_allocateもpool_resetも確
かにバイト数によらずO(1)でしょう。
しかし、割り付けた部分を必ず初期化するとか、実際のデータを書き込むとか
すると仮定するなら、他の記事に書いた通りGCを使う場合とオーダーは同じで
す。
前田敦司
In article <m3sma08...@nospam.maedapc.cc.tsukuba.ac.jp>, MAEDA Atusi <maeda...@ialab.is.tsukuba.ac.jp> writes
> しかしですね。以下の条件が満たされるならオーダーは変わんないですよ。
> ・割り付けた領域には、少なくとも一回データが書き込まれる(初期化でも可)
> ・ヒープサイズは生きているデータの量に比例して増加させてよい
> ・GCのルート集合の大きさは、高々生きているデータの量に比例する程度
2番目はちょっとずるいような気もするけど、その仮定だとO(N)に
なる気がする。ってことは、メモリが足りなくなるような状況でな
ければ、定数オーダの差しかないってことなのかな。
なんか、まずい場合があったような気がするんだけど、いまいち、
思い付かないなぁ。ってことは、そういうことなんだろうか?
んーと、append の場合も時間計算量はおんなじなんだけど、破壊
と非破壊だと、領域計算量が違いますよね。今の計算機は結構メモ
リスピードネックだったりするので、O(N^2)とかの計算だとゴミが
たくさんでないようにしないとまずいってのは、あるかな。
Shinji KONO wrote:
> アルゴリズム寄りってのが、
>
> とにかく、論理的には正しく動く
>
> ってことなら、確かに、LISPが最速かも知れない。
プログラムを作成することではなくアルゴリズムを作成することが目的であ
るプログラミングをするなら LISP が良いと言い替えた方が良い?(^^;;
;; 少なくとも C じゃやりたくない気分。
> プログラムを作成することではなくアルゴリズムを作成することが目的であ
> るプログラミングをするなら LISP が良いと言い替えた方が良い?(^^;;
はぁ? Greenspun's Tenth Rule って知りません?
わたしの部では *プログラム作成する目的* で (Common) Lisp 使ってます。
新規開発にはもちろんですが、お客さんのところから来る C, Fortran, Perl
諸々で書かれたモノの保守や拡張は、うちを出てくときには大抵 Lisp に置き
換えられてます :) Web service も Lisp でやってます。
--
KURODA, Hisao
Mathematical Systems Inc.
10F Four Seasons Bldg.
2-4-3 Shinjuku, Shinjuku-ku,
Tokyo 160-0022 Japan
Tel: +81-3-3358-1701
Fax: +81-3-3358-1727
URL: http://www.msi.co.jp/~kuroda
In article <71isavw...@hinttika.msi.co.jp>, KURODA Hisao <kur...@msi.co.jp> writes
> はぁ? Greenspun's Tenth Rule って知りません?
Any sufficiently complicated C or Fortran program contains an ad-hoc,
informally-specified bug-ridden slow implementation of half of Common Lisp.
ですか。「Common」ってのは嘘だろうて気がするけど、Lisp はそうかも。
そういう意味でも、やっぱりLISPは教えた方がいいんだよなぁ。
でも、制限した実装ですむから slow かどうかは知らない。
C++ とか Java だと、ある程度、データ構造がそろっているので、
割りと逃げられるかも知れない。
> わたしの部では *プログラム作成する目的* で (Common) Lisp 使ってます。
> 新規開発にはもちろんですが、お客さんのところから来る C, Fortran, Perl
> 諸々で書かれたモノの保守や拡張は、うちを出てくときには大抵 Lisp に置き
> 換えられてます :) Web service も Lisp でやってます。
(う、ある意味、迷惑かも...)
処理系は、Alegro ですか?
> Any sufficiently complicated C or Fortran program contains an ad-hoc,
> informally-specified bug-ridden slow implementation of half of Common Lisp.
> ですか。「Common」ってのは嘘だろうて気がするけど、Lisp はそうかも。
どういう意味ですか?
Common Lisp って ANSI CL の事です、ってのはいいですよね。
> そういう意味でも、やっぱりLISPは教えた方がいいんだよなぁ。
(Common) Lisp は教えといてもらいたいですが、LISP ならいいです…
> 処理系は、Alegro ですか?
Allegro が多いですね。
KURODA Hisao wrote:
> Narita Takaoki <tak...@aisoft.co.jp> writes:
>
>> プログラムを作成することではなくアルゴリズムを作成することが目的であ
>> るプログラミングをするなら LISP が良いと言い替えた方が良い?(^^;;
>
> はぁ? Greenspun's Tenth Rule って知りません?
いや別に「プログラムを作成することに向かない」とは言っていないわけで。
より特徴が尖鋭的に出てくる領域がアルゴリズム開発かなと。
まあ、保守やら何やら考えると実は Lisp が凄いってのはわかっているつも
りです(「レベルが低い。もっとわかれ」と言われりゃしまいですが)。です
から、もろもろ作成するに使うことに優位性が出るのはわかっている。
でも、世間的には既にはびこっている言語を押し退けてまで使わせるところ
まで信じてはくれない。「Lisp が C ほどに普及していないのは、結局 C
と比べて劣っているんだろう」と多くは考えているんではなかろうか?
;; もしくは「MS LISP 売っていないしなぁ」とか。こっちの方が理由とし
;; て大きい?(^^ LISP 陣営はマーケティングで負けている気がする。
In article <71acw7w...@hinttika.msi.co.jp>, KURODA Hisao <kur...@msi.co.jp> writes
> Common Lisp って ANSI CL の事です、ってのはいいですよね。
Common Lisp あんまり好きじゃないので。setf しまくるスタイル
は、ある意味でCっぽい感じ。便利だとは思うんですけど。あとコ
ンパイラを前提とした、複雑な呼び出しオプションが、ちょっと嫌
かな。そのあたりは、その第十規則とは関係ないですよね。
> (Common) Lisp は教えといてもらいたいですが、LISP ならいいです…
ふーん。一回だけ教えたことがあるんですが、やっぱり、scheme
の方がいいなと思った記憶があります。C++ と似ていて教える
ことが多いっていうか、例外が多いって言うか。
でも、最近は教えてないな。でも、たまに気が向くと、
Emacs Lisp の使い方を見せたりしてます。
特別授業でもやるか。
> Common Lisp あんまり好きじゃないので。setf しまくるスタイル
> は、ある意味でCっぽい感じ。
ええ、Lisp と C はバリバリ von Neuman 指向かと ;)
> あとコンパイラを前提とした、複雑な呼び出しオプションが、ちょっと嫌か
> な。そのあたりは、その第十規則とは関係ないですよね。
関係ありますとも。Lisp に限りませんがコンパイラ前提としないようじゃ、
とてものことに general purpose には使えない。c や fortran にかなわない。
個人的にはそう思います。
> 特別授業でもやるか。
Lisp のですか? c にしときませんか?
> (う、ある意味、迷惑かも...)
こういう反応する人に Lisp 教えられたんじゃ可哀想ですよね、学生さんも。
> > しかしですね。以下の条件が満たされるならオーダーは変わんないですよ。
> > ・割り付けた領域には、少なくとも一回データが書き込まれる(初期化でも可)
> > ・ヒープサイズは生きているデータの量に比例して増加させてよい
> > ・GCのルート集合の大きさは、高々生きているデータの量に比例する程度
>
> 2番目はちょっとずるいような気もするけど、その仮定だとO(N)に
> なる気がする。ってことは、メモリが足りなくなるような状況でな
> ければ、定数オーダの差しかないってことなのかな。
生きているデータの何倍も取るというわけではないです。
ふつうは生きているデータ量の50%くらい空きがあれば(つまりメモリ量は1.5
倍)だいたいOKかと。
まあ、どんなメモリ管理をしても、少しは余裕が必要ですから。ずるいと言う
ほどでもないかと。
> なんか、まずい場合があったような気がするんだけど、いまいち、
> 思い付かないなぁ。ってことは、そういうことなんだろうか?
>
> んーと、append の場合も時間計算量はおんなじなんだけど、破壊
> と非破壊だと、領域計算量が違いますよね。今の計算機は結構メモ
> リスピードネックだったりするので、O(N^2)とかの計算だとゴミが
> たくさんでないようにしないとまずいってのは、あるかな。
木構造だと破壊でも非破壊でも大差ないと思いますが、グラフを表現するには
破壊的書き換えを使うことが多いかも。で、本来グラフが必要なところを木だ
けでやろうとすると、領域計算量が指数関数で増えたりとか。
前田敦司
教育用には、やっぱりインタプリタだろとか僕は思います。
In article <717jrbv...@hinttika.msi.co.jp>, KURODA Hisao <kur...@msi.co.jp> writes
> 関係ありますとも。Lisp に限りませんがコンパイラ前提としないようじゃ、
> とてものことに general purpose には使えない。c や fortran にかなわない。
> 個人的にはそう思います。
確かに、Common Lisp は、コンパイラ前提のLISPで、まさに、
C や Fortran のように使いたいために設計されるんですよね。
黒田さんは、Common Lisp で、コンパイラ向けの型制限を使いまく
る方ですか? ある意味では、C や Fortran に勝つために導入され
たものですよね。そういう使い方するなら、C でいいかなぁ。
でも、僕に取ってのLISPというと、 シンプルな構文とシンプルな
操作意味論を持っていて、その上に、マクロでシンタックスシュガ
ーをかけるっていうものだっていう偏見があるんだよね。それで、
十分にコンパイラが最適化をかけられる筈だと言う感じで。
そういう意味で、Common Lisp は、僕に取ってはLISPっぽくないLisp
ってわけです。
> > (う、ある意味、迷惑かも...)
> こういう反応する人に Lisp 教えられたんじゃ可哀想ですよね、学生さんも。
元のソースを尊重する方なので。元がLISPなら、LISP を尊重しま
す。
新規開発はともかく、Lisp以外の言語のプログラムの保守や拡張をLisp
に置き換えて動作チェックやってもLispの方が生産性が高いってことで
しょうか?
と言うか、お客さんはスンナリ置き換えにOK出すんでしょうか?
----
みなみ
> 黒田さんは、Common Lisp で、コンパイラ向けの型制限を使いまく
> る方ですか?
使い *まくり* はしませんが、必要なら使います。
例えばディジタルフィルタとかフーリエ変換とか型宣言もしないで、
float の boxing をガンガン起こしまくったものを、
お客さんにリリースするわけにいかないので。
> ある意味では、C や Fortran に勝つために導入されたものですよね。
そうなんですか? よくわかりません。別に、
c や fortran をヌキにしても、コンパイラを考えないようなナイーブなもの
使ってたんではせいぜいその言語のネガティブキャンペーンにしかならないように
思います。
> そういう使い方するなら、C でいいかなぁ。
tenth rule によれば、こういう人が ad hoc informally-specified
bug-ridden slow implementation を延々と積みあげていくわけですよね。
> でも、僕に取ってのLISPというと、 シンプルな構文とシンプルな
> 操作意味論を持っていて、その上に、マクロでシンタックスシュガ
> ーをかけるっていうものだっていう偏見があるんだよね。それで、
> 十分にコンパイラが最適化をかけられる筈だと言う感じで。
macro を syntax 抽象に使う、という理解はいいですが、
コンパイラに最適化を指示させるんなら一般に compiler-macro ですね。
ですが型宣言が無くて macro だけで充分な最適化を指示できる方法というの
がわたしには思いうかびません。
> そういう意味で、Common Lisp は、僕に取ってはLISPっぽくないLisp
> ってわけです。
Common Lisp 以外にちゃんと macro や
compiler macro が使えるものって何を使われるんでしょう?
> Lisp以外の言語のプログラムの保守や拡張をLisp
> に置き換えて動作チェックやってもLispの方が生産性が高いってことで
> しょうか?
ええ、もちろんそうです。そうなんですけれども、
> お客さんはスンナリ置き換えにOK出すんでしょうか?
生産性の向上を訴えるぐらいでは ok でません。
生産性はお客さん(使う方)にとっては関係の無い話ですから。
;; そのぶん見積り額下げるように言われるのがオチです。
お客さんにとって大事なのは、性能であり、頑強性であり、機能拡張性であり、
ポータビリティであるわけです。あと、スタンドアローンアプリの場合ならば
パッチが動的にあてられるだとか、サーバアプリの場合ならばプロセスを止め
ずに修正が可能であるとか、運用上の柔軟性とでも言うんでしょうか、そういっ
た諸々です。
瞬間風速的なベンチマークをいくら言ってもしょうがないんで、トータル的な
戦略で堀を埋めていく、といったことができないと、また、そういうアプローチ
が有効なアプリケーションに対してでないと難しいですね。
一番良いのは、先に動いてるもの見せちゃうことです。
In article <71r7pgt...@hinttika.msi.co.jp>, KURODA Hisao <kur...@msi.co.jp> writes
> 一番良いのは、先に動いてるもの見せちゃうことです。
そう言うのには、LISPは最適な言語なんだよな~
> お客さんにとって大事なのは、性能であり、頑強性であり、機能拡張性であり、
> ポータビリティであるわけです。あと、スタンドアローンアプリの場合ならば
> パッチが動的にあてられるだとか、サーバアプリの場合ならばプロセスを止め
> ずに修正が可能であるとか、運用上の柔軟性とでも言うんでしょうか、そういっ
> た諸々です。
そこの原点には「インタプリタ」ってのがあると思うんだけど...
あるいはプログラミング環境かな。
package と binary patch
に慣らされちゃってますからね。
> そこの原点には「インタプリタ」ってのがあると思うんだけど...
いいえ、完全な誤解だと思います。
動的な patch あてには load があれば良いだけですし、
動的な program 変更には compile と load があれば良い。
もちろんそういった operation を行なうための i/f 、具体的には listener
が必要ですが、listener と interpreter はまた別物です。
CMUCL には listner がありますが、普通我々が期待するところの
interpreter は無いです。以下の例参照ください。
% lisp
CMU Common Lisp 18c, running on hinttika.msi.co.jp
Send questions to cmucl...@cons.org. and bug reports to cmuc...@cons.org.
Loaded subsystems:
Python 1.0, target Intel x86
CLOS based on PCL version: September 16 92 PCL (f)
* (defmacro foo (x) `(car ,x)) ; マクロ foo の定義
FOO
* (defun bar (x) (foo x)) ; foo を呼ぶ関数 bar の定義
BAR
* (bar '(1 2 3))
1
* (defmacro foo (x) `(cdr ,x)) ; マクロ foo の再定義
FOO
* (bar '(1 2 3)) ; でも bar から呼ばれる foo は昔のまま
1
* (defun bar (x) (foo x)) ; bar を 再定義あるいは再コンパイルして
; はじめて新たな foo が呼び出される
BAR
* (bar '(1 2 3))
(2 3)
*
(削る分や変更する分は別にして)元々持っていた機能や性能も全て
担保した上での話で宜しいでしょうか。
>> お客さんはスンナリ置き換えにOK出すんでしょうか?
>
>生産性の向上を訴えるぐらいでは ok でません。
>生産性はお客さん(使う方)にとっては関係の無い話ですから。
>;; そのぶん見積り額下げるように言われるのがオチです。
それはその通り。他にも金額同じでも納期もっと短くしろと
言われるのも嫌だし。
ただ今はLispは商業的にはマイナーな存在なので、お客さんの
・「次はウチでメンテしようとしても、Lispじゃできないなあ」
・「オタク、これからもLispずっと同じ値段でサポートし続けられ
るように人を確保しておとくの? めったなことじゃ潰れない超優良
企業?」
・(多分心の中で)「よその外注に廻せなくなるなあ」(技術や品質
以外の要因で外注を変えることもあるし)
等々もうまくクリアできるの? なのでした。
------
みなみ@「そんな面倒な客とは付き合わん」、一度は言ってみたい(^^;
> >> もLispの方が生産性が高いってことでしょうか?
> 元々持っていた機能や性能も全て担保した上での話で宜しいでしょうか。
もちろんです。遊びでやってるわけではないので。
> ・「次はウチでメンテしようとしても、Lispじゃできないなあ」
> ・「オタク、これからもLispずっと同じ値段でサポートし続けられ
> るように人を確保しておとくの? めったなことじゃ潰れない超優良
> 企業?」
> ・(多分心の中で)「よその外注に廻せなくなるなあ」(技術や品質
> 以外の要因で外注を変えることもあるし)
> 等々もうまくクリアできるの? なのでした。
話すと長くなるしケースバイケースでもあるので詳細は言いませんが、クリア
できます。この程度のこともクリアできないんじゃ Lisp は退けといても我々
のやってるような仕事そのものができません。
よくいるんですよ。「Lisp は好きなんだけどもお客さんが使わせてくれなくっ
てね」って、そりゃお客さんも使わせてくれませんよ、そんな主体性の無い人
に…
#プログラミング言語と保守の質問をしたいのでfj.comp.programmingにも
#ふって、Subject:を変えました。
KURODA Hisao <kur...@msi.co.jp> writes:
> > ・「次はウチでメンテしようとしても、Lispじゃできないなあ」
> > ・「オタク、これからもLispずっと同じ値段でサポートし続けられ
> > るように人を確保しておとくの? めったなことじゃ潰れない超優良
> > 企業?」
> > ・(多分心の中で)「よその外注に廻せなくなるなあ」(技術や品質
> > 以外の要因で外注を変えることもあるし)
> > 等々もうまくクリアできるの? なのでした。
>
> 話すと長くなるしケースバイケースでもあるので詳細は言いませんが、クリア
> できます。この程度のこともクリアできないんじゃ Lisp は退けといても我々
> のやってるような仕事そのものができません。
>
> よくいるんですよ。「Lisp は好きなんだけどもお客さんが使わせてくれなくっ
> てね」って、そりゃお客さんも使わせてくれませんよ、そんな主体性の無い人
> に…
す、すみません。なんでもよいので、このような事例でお客様を納得させた
テクニックを差し支えない範囲で教えて下さい。お願いします。
#これができれば、他にもいろいろ応用が...ど、どうやったのだろう?
> #プログラミング言語と保守の質問をしたいのでfj.comp.programmingにも
> #ふって、Subject:を変えました。
cross post はしないことに決めているので f.c.pogramming 外します。
> このような事例でお客様を納得させたテクニックを差し支えない範囲で教え
> て下さい。
;; 「テクニック」ですか… ずいぶん軽いノリですね…
まぁそれは良いとして、
そうしないとお給料もらえないところまで自分を追い込んでみてくださいな。
後は自ずと…
僕は、Common Lisp/CLOS は、C++ 的なところがあって嫌いなんで
す。その中心には、Common Lisp の compiler 偏重があるんだよね。
C++ の持つ「中途半端な、最適化を、考慮した仕様」(中途半端は
最適化、あるいは、全体にかかる) ってのがCommon Lisp にもある
気がする。他方で「Compiler の最適化を前提とした、複雑な機能」
ってのもある。こういう言語(C++ / CLOS) は教えるのがすごく大
変。
で、「Interpreter を重視していれば、そうはならなかった」と僕
は考えます。で、第十則みたいなCommon Lisp の良いところは、実
は、Interpreter から来ていると僕は信じているわけ。それが「基
本的には」に掛かっている心です。
で、Interpreter を重視しないなら S式に拘る必要はないわけで、
実際、ML とかは、S式じゃない構文なわけです。もちろん、Listner
もあります。それでもS式なのはなんでかというと、S式でないと Lisp
じゃないからなんだよね。
ただ、商業利用に耐えるLispっていうとCommon Lispに、なっちゃ
うんだよな。まぁ、そういう一面を持つ Lisp で、主流であるのは
認めます。Scheme 使ってもいいんだけど、Scheme は Lisp じゃな
いっていう人の方が多いか。
In article <71isast...@hinttika.msi.co.jp>, KURODA Hisao <kur...@msi.co.jp> writes
> 動的な patch あてには load があれば良いだけですし、
> 動的な program 変更には compile と load があれば良い。
まぁ、ねぇ。C でも、あるっちゃあるんだよな。dlopen とか。
> もちろんそういった operation を行なうための i/f 、具体的には listener
> が必要ですが、listener と interpreter はまた別物です。
C だと、gdb が listener になるか。(そうなのか?!)
> 「Interpreter を重視していれば、そうはならなかった」
消えちゃってたんじゃないでしょうか。言語自身が。
> で、Interpreter を重視しないなら S式に拘る必要はないわけで、
わかってないですね…
CL の macro が CL の macro でいられるのはS式のおかげでしょうに。
> Scheme 使ってもいいんだけど、Scheme は Lisp じゃないっていう人の方が
> 多いか。
多くはないでしょう。
ちなみにわたし個人はそう思ってます。
空リストが偽を表さない Lisp なんて認めるわけには行きません :)
symbol も macro も無いし :-P
> > 動的な program 変更には compile と load があれば良い。
> まぁ、ねぇ。C でも、あるっちゃあるんだよな。dlopen とか。
c は c から c の runtime 環境を使って c compiler が呼べませんよね。
この差は大きいと思います。
> C だと、gdb が listener になるか。(そうなのか?!)
ええ、賛成です。
Lisp programmer はいつも debugger から仕事しているようなものですから。
In article <71656rs...@hinttika.msi.co.jp>, KURODA Hisao <kur...@msi.co.jp> writes
> わかってないですね…
うん。そのあたりわかれば、きっと、気持ちの良い世界なんだよね。
> CL の macro が CL の macro でいられるのはS式のおかげでしょうに。
高階関数っていうアプローチもあって、マクロとどっちが良いかっ
て言うと、理論的には高階関数の方が良いみたいですね。「理論的
には」です。MLer は、きっと、Common Lisp で出来ることは全て
MLで出来ると言うだろうな。
マクロには、マクロの良さがあるんだけどさ。ただ、シンタックス
エラーは嫌でしょ? マクロのデバッグって、どうしてます?
> ko...@ie.u-ryukyu.ac.jp (Shinji KONO) writes:
> > 「Interpreter を重視していれば、そうはならなかった」
> 消えちゃってたんじゃないでしょうか。言語自身が。
いや、まぁ、Scheme も残っているっちゃ残っているわけだし。Perl
も Emacs lisp も残っているわけだし。消えるってことはなかった
と思うんだけど... Common Lisp って名前自体が「他のは許さん!」
みたいな強圧的な所があって、それが少し良くなかったかなぁ。
> c は c から c の runtime 環境を使って c compiler が呼べませんよね。
> この差は大きいと思います。
まぁねぇ。できないわけじゃないんだけど標準的な手法がないんで
すよね。
僕は、C と「Common LispでないLisp」には、重くない制限された
自由度みたいなものがあると思うんだ。Common Lisp も C++ には、
「重い過度に自由な部分」があると思う。その部分を使わなければ
両方とも悪くないんだよな~
だけど、必ず「そういう所を極限まで使うプログラム」ってのを書
くのがいてさ... C++ のTemplate マニアと、Common Lisp のマク
ロマニアと、なんか似てない? そんな感じなんだけど...
いや、別にわかってくれなくてもいいんですけど...
ko...@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 <3990434...@rananim.ie.u-ryukyu.ac.jp> ko...@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と違って、マクロ専用の全く別の文法を導入したりはしていない。
前田敦司
In article <m3isar2...@nospam.maedapc.cc.tsukuba.ac.jp>, MAEDA Atusi <maeda...@ialab.is.tsukuba.ac.jp> writes
> LispがS式に拘る理由は、くろださんのおっしゃる通りマクロだと思いますよ。
そう言えば、S式で書くCってのをどこかで作っていたなぁ。#define とか
inline よりいいかも。
> 高階関数でマクロみたいに構文拡張しようと思うと、Haskellのようなlazyな
> 言語じゃないと難しいですね。
もちろん、高階関数とマクロは別物なんですけどね。マクロは、問
題が多い。楽しいんだけど。
マクロ構文 => 構文生成 => コード生成 => 実行
と段階が増えますからね。
構文 => 実行
ってのが、もう少し見直されても良いと思うんだけど。インタプリタだから
コンパイルできなくて遅いっていう時代じゃぁないと思う。
> そういう「ニッチ」に自らを封じ込めた特殊用途の言語としてでなく、汎用の
> 言語であり続けるためには、インタプリタじゃダメだと。(耳が痛い。)
当時の要求が(Common Lisp も C++ も)そうだったんでしょうね。
Java はちょっと時代がずれて、差別化の意味でもByte code + JIT
になったんでしょう。その後は、なんとなくscript言語以外は新し
い言語は、あまり話がないわけですけど、そろそろ、なんか別なも
のが欲しいなぁ。
In article <3990465...@rananim.ie.u-ryukyu.ac.jp>, Shinji KONO wrote:
>河野真治 @ 琉球大学情報工学です。
>Java はちょっと時代がずれて、差別化の意味でもByte code + JIT
>になったんでしょう。
Byte code を採用した一番大きな理由はセキュリティ確保の為だった様な記
憶があります.もちろん,オブジェクトレベルでのポータビリティとか,他
にもメリットは多々あるわけですが.
#デメリットは実行速度だけ(?)
#RISCy な CPU だとインタプリタとの速度差が大きくなるし...(多分
>その後は、なんとなくscript言語以外は新し
>い言語は、あまり話がないわけですけど、そろそろ、なんか別なも
>のが欲しいなぁ。
確かに.
--
Hideki Kato <mailto:ka...@pop12.odn.ne.jp>
> > LispがS式に拘る理由は、くろださんのおっしゃる通りマクロだと思いますよ。
>
> そう言えば、S式で書くCってのをどこかで作っていたなぁ。#define とか
> inline よりいいかも。
「S式ベースC言語SC」ですか。
S式を変換するマクロがCで書けるわけじゃないですけどね。
> 構文 => 実行
>
> ってのが、もう少し見直されても良いと思うんだけど。インタプリタだから
> コンパイルできなくて遅いっていう時代じゃぁないと思う。
うーん。でも遅いし。
(逆に、レジスタを活用できるネイティブコードと、活用しづらいインタプ
リタの差は開きつつあるかも。)
> > そういう「ニッチ」に自らを封じ込めた特殊用途の言語としてでなく、汎用の
> > 言語であり続けるためには、インタプリタじゃダメだと。(耳が痛い。)
>
> 当時の要求が(Common Lisp も C++ も)そうだったんでしょうね。
> Java はちょっと時代がずれて、差別化の意味でもByte code + JIT
> になったんでしょう。
bytecodeと動的ロードは差別化のために必要だった。で、その言語仕様を守っ
たままネイティブコードにするには、JITしかなかったということでは。
つまり、「ネイティブコードが必須」という要求はJavaでも同じ。
前田敦司
LISP の LISP らしさって言うと、
S式 ((カッコ!)) の構文
それに対して定義された操作意味論
ですよね。あと、
リストを中心としたデータ構造 (ってのは Common Lisp では時代遅れ?)
GC (触れてはいけない話題かも知れないけど)
となるわけですけど。
構文 = データ構造
ってのは便利ですよね。覚えるものが少ないところが良いはずだったのだが...
Common LISPは、ちょっと多すぎるかなぁ。
In article <m3ekley...@nospam.maedapc.cc.tsukuba.ac.jp>, MAEDA Atusi <maeda...@ialab.is.tsukuba.ac.jp> writes
> > ってのが、もう少し見直されても良いと思うんだけど。インタプリタだから
> > コンパイルできなくて遅いっていう時代じゃぁないと思う。
> うーん。でも遅いし。
インタプリタ向きのセマンティクスを持っているからと言ってコン
パイル結果が遅いとは限らないっていう意味です。まぁ、Dynamic
scope とかは向いてないだろうとは思うけどさ。
コンパイラが遅くなるセマンティクスってのは、例えば、実行時に
ならないと特定できない情報が多い場合です。良くあるのは型が決
まらない場合ですね。だからオブジェクト指向言語はコンパイラで
も実はかなり遅い。あと、C++ とかBasic とかで、あるいは、Perl
もそうなんだけど、文字列とかハッシュテーブルとかの手間のかか
るデータ構造中心の処理をされちゃうと、コンパイラはあまり頑張
れない。
Common Lisp もいろいろ工夫されているけど、Compile 結果を早く
するためには注意してプログラムする必要がありますね。
> マクロのデバッグって、どうしてます?
macroexpand と macroexpand-1 で展開結果が見えるわけですから、
マクロだからって特別なデバッグがあるわけではないです。
Allegro CL には、
fi:lisp-macroexpand とか fi:lisp-macroexpand-recursively とか
良い elisp command があって重宝しますね。
In article <71pt4yp...@hinttika.msi.co.jp>, KURODA Hisao <kur...@msi.co.jp> writes
> macroexpand と macroexpand-1 で展開結果が見えるわけですから、
> マクロだからって特別なデバッグがあるわけではないです。
Lisp のデバッガは充実しているからなぁ。
> Allegro CL には、
> fi:lisp-macroexpand とか fi:lisp-macroexpand-recursively とか
> 良い elisp command があって重宝しますね。
一段展開してくれるのがあるのは便利そうだな。
とか話していると、久しぶりに使ってみたくなりますね。