トップページtech
1001コメント388KB

Common Lisp, Scheme Part 14

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2005/11/18(金) 10:02:06
過去スレ
Part1: http://piza2.2ch.net/tech/kako/987/987169286.html
Part2: http://pc.2ch.net/tech/kako/1002/10025/1002584344.html
Part3: http://pc.2ch.net/tech/kako/1008/10082/1008220265.html
Part4: http://pc.2ch.net/tech/kako/1016/10162/1016211619.html
Part5: http://pc3.2ch.net/tech/kako/1023/10230/1023091882.html
Part6: http://pc3.2ch.net/tech/kako/1031/10315/1031560687.html
Part7: http://pc5.2ch.net/tech/kako/1042/10421/1042167213.html
Part8: http://pc5.2ch.net/tech/kako/1058/10582/1058263391.html
Part9: http://pc2.2ch.net/test/read.cgi/tech/1069594582/
Part10: http://pc5.2ch.net/test/read.cgi/tech/1075630259/
Part11: http://pc5.2ch.net/test/read.cgi/tech/1091456033/
Part12: http://pc8.2ch.net/test/read.cgi/tech/1100229366/
Part13: http://pc8.2ch.net/test/read.cgi/tech/1115901841/
0232デフォルトの名無しさん2005/12/23(金) 20:29:38
そりゃ意味論の話だから。
0233デフォルトの名無しさん2005/12/23(金) 21:42:59
>>231
たまには意味あるんじゃないか?
名前空間を汚さずにラムダ式だけで計算できるから
実例は知らないけど…
0234デフォルトの名無しさん2005/12/23(金) 22:51:17
>>231
for-eachとかcall-with-*とかに再帰的な手続きを渡せたりとか。
0235デフォルトの名無しさん2005/12/24(土) 04:58:28
letrec使えばいいじゃん。
0236デフォルトの名無しさん2005/12/24(土) 12:45:41
>>231
コンパイラ作る時に使うとか
0237デフォルトの名無しさん2005/12/25(日) 02:45:47
http://luisguillermo.com/PL_ega.gif
ちょwwwww LISPwwwww
0238デフォルトの名無しさん2005/12/25(日) 03:19:10
>>237
何を表現してるのかさっぱりわからんwwwww
0239デフォルトの名無しさん2005/12/25(日) 12:52:44
http://www.yuasa.kuis.kyoto-u.ac.jp/~nobu/study/palm/chap2.html
ここの2.6に書いてある、ダイナミックヒープ中の一時的なビットベクタを使う
とはどういう意味なんでしょうか。
どこがマークされたか保存しておいて、スイープの時に照し合わせるんでしょうか?
だとしたら滅茶苦茶時間かかると思うんですけど。

リストにネイティブなポインタを使うと下位2ビットしか使えないんですが
そこをGCのフラグに使うのが一般的なんでしょうか?

それともポインタの代わりに配列のインデックスを使った方がいいんでしょうか?
これのやり方がいまいち良く分かりません。
0240デフォルトの名無しさん2005/12/25(日) 13:12:05
対象ポインタ中にmark bitを取るとmarkするだけでそのページが
dirtyになるから、incremental gcとかが面倒にならんかな。
まあ、write barrierの実装方法にもよるし、ケースバイケースだね。
0241デフォルトの名無しさん2005/12/25(日) 21:45:08
>>237
とりあえずBASICは前科者

あとFORTRANは怒らせないほうがいい
0242デフォルトの名無しさん2005/12/25(日) 22:11:06
>>239
src/store.c読め。
markBitという変数がビットベクタ。
わざわざLispMeのソース持ってきて調べちゃったじゃないか。
ちなみにセルはインデックスになっていた。
これのメリットはフラグビットが多く取れる事、永続化する際に
アドレス変換しなくて良い(そのままfwrite/fread可)といった点。
0243デフォルトの名無しさん2005/12/25(日) 23:22:53
>>242
読まずに質問してすいません。
マークビットにインデックスで直接アクセスするので、余計な時間はかからないんですね。
フラグビットが多く取れることやダンプが簡単なことはとっても魅力的なんですけど
メモリの無駄が多いことと、いっぱいになったときに reallocするのが重そうなので
なんだかためらってしまいます。
reallocしない方法も考えられますが、生きてるセルの間が大きくなったりしたら
困る気がします。
0244デフォルトの名無しさん2005/12/25(日) 23:30:15
ヒープが小さいんだからたいして困らん。
0245デフォルトの名無しさん2005/12/25(日) 23:43:29
>>244
それは Palmの場合ですよね。
LispMeではヒープのサイズは固定ですが、一般にはヒープサイズを可変にした方が
いいと思ったので。
言葉足らずですいません。
0246デフォルトの名無しさん2005/12/30(金) 06:23:00
CL でも Scheme でもないけど、xlispstat の本が出たみたい

http://www.kohgakusha.co.jp/books/detail/4-7775-1180-4
0247デフォルトの名無しさん2005/12/30(金) 13:45:12
うっ、微妙だな…目次みた感じだと、まだ統計を習ってない(かつ R とかにで
あってない)人の入門向けってとこかな。高校生くらいには丁度いいのかも。

まぁ、せっかくここまで揃えた Lisp 本コレクションが欠けるのも悔しいので
買ってしまうんだけどね…。
0248デフォルトの名無しさん2005/12/30(金) 18:50:02
高校生ですが、その本の
「計算機科学の方面では『λ算法』とかいうものがあると聞きますが、
詳しいことは筆者もよく知りません」
という記述はどうかと思いました。
0249デフォルトの名無しさん2005/12/30(金) 18:57:45
CS 専攻じゃなければ名前だけって人も多いだろう。
計算モデルを知らなくても使えるからいいじゃん。
無意味にしったかぶりするよりは好印象。
0250デフォルトの名無しさん2005/12/30(金) 22:46:19
でも本に書くなら調べて簡単な註釈なりリファレンスなり示しとけと。
0251デフォルトの名無しさん2005/12/31(土) 01:51:57
工学社の本なら「筆者もよく知りません(笑」でなかっただけマシだろ。
あそこパソ通時代のノリそのままの半可通本が多いわけだし
0252デフォルトの名無しさん2005/12/31(土) 09:59:50
CS専攻(だった。10年前)でもλ算法知りませんが何か?
0253デフォルトの名無しさん2005/12/31(土) 10:58:52
たしかに、λ「算法」は聞いたことないなあ
0254デフォルトの名無しさん2005/12/31(土) 12:41:46
無知を自慢するなよ
0255デフォルトの名無しさん2005/12/31(土) 13:28:20
λ...
 トボトボ
0256デフォルトの名無しさん2005/12/31(土) 15:05:05
>>254
「無知の知」という言葉もある。
知らないことを自覚しているのはただ知らないよりもマシではあるまいか。
無論、知っている方がよりよいが。
02572532005/12/31(土) 15:27:33
ああ、λ算法ともいうのか。。
今検索して初めて知った。
0258デフォルトの名無しさん2005/12/31(土) 15:28:32
lambda calculi
0259デフォルトの名無しさん2005/12/31(土) 15:34:17
むちむち
0260デフォルトの名無しさん2005/12/31(土) 17:29:13
ラムダ算法騎士団乙
0261デフォルトの名無しさん2005/12/31(土) 22:30:19
この無知の行進に驚いてしまった自分は古い人間なんだろうか。


# ま、数学基礎論専攻だったので知ってるのは当たり前なんですが
0262デフォルトの名無しさん2005/12/31(土) 23:05:56
>>261
そんな事はどうでも良いから、Lisp の話題を振ってくれ。
0263デフォルトの名無しさん2005/12/31(土) 23:24:40
bSI1
0264デフォルトの名無しさん2005/12/31(土) 23:56:35
これだけの無知っぷりだと、話題を振るのもためらわれます。
0265デフォルトの名無しさん2006/01/01(日) 00:42:31
ほぉ
0266デフォルトの名無しさん2006/01/01(日) 01:23:58
L Sharp (Lisp for .NET) の新版がでましたね.Scheme でも Common でもない
けどがんがってほしい.原理主義者ではない俺は気にしない.
0267 【大吉】 【39円】 2006/01/01(日) 11:52:23
LISPの運勢
0268デフォルトの名無しさん2006/01/01(日) 11:53:30
安い……
0269 【豚】 【973円】 2006/01/01(日) 14:13:06
Schemeの運勢
0270デフォルトの名無しさん2006/01/01(日) 14:14:36
λ算法なんてLisp/Scheme使いでも知ってる人間のほうが少数では?
そりゃ「名前くらいなら聞いたことが」って人間は大半だろうがその数学的な概念をきちんと理解している人間が
どれくらいいるってんだよ。
0271デフォルトの名無しさん2006/01/01(日) 15:17:36
きちんと理解してない人間がLisp, Schemeを語るなんてありえない。
ここもレベルが下がったな。
0272 【大吉】 2006/01/01(日) 15:20:21
レベル高かったの?ここ。
0273デフォルトの名無しさん2006/01/01(日) 15:50:13

http://en.wikipedia.org/wiki/Lisp_programming_language
http://en.wikipedia.org/wiki/Scheme_programming_language
http://en.wikipedia.org/wiki/Programming_paradigm
http://en.wikipedia.org/wiki/Foundations_of_mathematics
http://en.wikipedia.org/wiki/Lambda_calculus
0274 【小吉】 【988円】 2006/01/01(日) 16:28:23
>>272
ム板でも指折りの高レベルスレ
0275デフォルトの名無しさん2006/01/01(日) 17:23:18
>>271
一応わかっている(つもりの者)だが、
Lisp Scheme のどの辺の知識を知るのに
わかっていないとありえないとおっしゃるのかな
0276デフォルトの名無しさん2006/01/02(月) 03:23:53
初心者ですが
(car . ((quote . ((20 . (10 . NIL)) . NIL)) . NIL))
これを評価する場合、
→(quote . ((20 . (10 . NIL)) . NIL))
→(20 . (10 . NIL))
ときて、なぜ
→((20 . (10 . NIL)) . nil)
となって
答え:(20 . (10 . NIL))
にならないんですか?
??(・∀・)何か勘違いしてる...?
0277デフォルトの名無しさん2006/01/02(月) 03:37:11
意味不明。
どういう式を評価してみたのか、自分が入力したものをそのまま載せてみ。
02782762006/01/02(月) 03:50:46
式は
(car . ((quote . ((20 . (10 . NIL)) . NIL)) . NIL))
これです
(car '(20 10))
これをドット対に直してみて
(car . ((quote . ((20 . (10 . NIL)) . NIL)) . NIL))
となったんですけど
頭で考えると>>276で書いた手順で答えが
(20 . (10 . NIL))
になっちゃうんですけど実際に評価してみると
20
となります。
根本的なところで勘違いしてる悪寒です。。。
0279!omikuji !dama 2006/01/02(月) 04:15:51
>>278
最初に言っておくと、評価プロセスを学ぶ上では、
データ構造としてのリストのドット対表記は使う意味が無い。

(car '(20 10)) を順に辿っていくと、
まず評価のはじめとして、関数とその引数が全て評価される。
特殊形式のquoteもこの時に取れる。

 car => #<function car>
 '(20 10) => (20 10)

#<function car>とは、シンボルcarに束縛された関数そのものを指す。
そして、ここまでの評価の中間結果として以下が得られる。

(#<function car> (20 10))

最後に、リスト先頭の#<primitive car>が(20 10)を引数として関数適用され、
その結果として20が返却される。
0280!omikuji !dama 2006/01/02(月) 04:26:55
最後のは#<primitive car>じゃなくて#<function car>の間違いね。
この#<〜>という表記の仕方は処理系によって変化する。
例えば#<primitive car>だったり#<closure 00abcdef>など。
ちなみに評価器で#<〜>と出力されるオブジェクトは基本的にreadできない。
02812762006/01/02(月) 04:42:26
>>279-280
新年早々ご親切にありがとうございました。
0282デフォルトの名無しさん2006/01/02(月) 18:21:23
() と '() について質問させてくらはい
(cons 1 ()) -> (1)
(cons 1 '()) -> (1)
どちらも一緒ですよね
だから構文解析するときどちらも nil として
返すようにしているのですが、問題でしょうか?
0283デフォルトの名無しさん2006/01/02(月) 18:32:10
write readしてequalで一致しなかったら、
悲しいと俺は思う
0284デフォルトの名無しさん2006/01/02(月) 18:42:15
>>282
(consp ()) => NIL
(consp '()) => NIL
(consp ''()) => T

'()と()が同じになるってことは''()と'()が同じってことで、
つまり''()と()は同じってことになる?
やっぱ問題あるような気がするけど。
0285デフォルトの名無しさん2006/01/02(月) 18:57:42
>>284
なるほど、''() は pair ですよね、(eval ()) と (eval '()) が
ともに () だからといって、一緒くたにしちゃだめですね、なんか
ぼけてました。
0286デフォルトの名無しさん2006/01/02(月) 21:29:20
>>284
同じではなく NIL というシンボルの変数としての値が NIL だというだけ。
0287デフォルトの名無しさん2006/01/02(月) 22:58:47
>>3
URL 変わってた。次にスレ立てする人は気をつけてちょ。

慶應の授業のページ・記号処理プログラミング 2005
http://web.sfc.keio.ac.jp/~t02064si/lisp2005/

;; GCL 使ってんのね。2006 の講義では SBCL の Windows 版が使える頃じゃないかな。
0288デフォルトの名無しさん2006/01/03(火) 15:47:24
素朴な疑問なんだけど (concatenate 'string "foo" "bar") は、何で
(concatenate "foo" "bar") や (concatenate-string "foo" "bar")
じゃないんだろう。実際は誤差の範囲だとしても、パフォーマンスペナルティ
が気になる。マクロでもないみたいだし。歴史的な理由かな?
0289デフォルトの名無しさん2006/01/03(火) 18:00:44
>>288
処理系によってはcompiler macro定義してるから、typeが定数なら
パフォーマンスは気にしなくていいんじゃね? Allegroで試したら
string専用の内部関数の呼び出しにコンパイルされてたよ。
仕様としては、中途半端にジェネリックなところが気持ち悪いと思うが。
0290デフォルトの名無しさん2006/01/04(水) 00:15:40
中途半端にジェネリックってのはまあ、歴史をしょってるから仕方ないんじゃね。
0291デフォルトの名無しさん2006/01/04(水) 03:30:07
>>289,290
ありがとうございます。Allegro ではマクロになってるんですね。
自分が使ってるコンパイラをもう少し調べてみます。
0292デフォルトの名無しさん2006/01/07(土) 01:38:01
最古のScheme処理系ってなんだろな
0293デフォルトの名無しさん2006/01/07(土) 01:51:00
>>292
SussmanとSteeleが1975年頃に最初の処理系を作ったと言われている。
当初"Schemer"という名前で計画されていたが、そのとき使用したITSというOSの
ファイル名が6文字までだったために"Scheme"という名前になった。
0294デフォルトの名無しさん2006/01/07(土) 05:21:28
>>292
SussmanとSteeleの論文(MIT AI-memo 349, 1975)に全ソースコードが
載ってるよ。実装言語はLISP。今のSchemeとはちょっと趣が違う。
で、たぶん2番目に古い処理系はSteeleによる最適化コンパイラRABBIT。
その後SteeleはSchemeチップの設計もやってる。
全部オンラインで読めるよ。
http://library.readscheme.org/page1.html

0295デフォルトの名無しさん2006/01/08(日) 01:18:51
その後SteeleはJavaの設計にも携わってるんでしょ。
すごい人だなー。
0296デフォルトの名無しさん2006/01/08(日) 01:22:07
Steele は色んな所に引っ張り出されてるよ。
CL は勿論、ECMAScript とか C とか。Java の後は Sun で Fortran の研究してたような。
02972922006/01/08(日) 02:56:31
>>293-294
あざーっす
0298デフォルトの名無しさん2006/01/08(日) 08:14:33
>>296
今のお仕事は Fortress だね。
http://research.sun.com/projects/plrg/fortress0785.pdf
って lisp に関係ないけどな。
0299デフォルトの名無しさん2006/01/08(日) 14:48:03
そういうことに詳しいおまいらも凄いよ
院生?
0300GLS2006/01/08(日) 17:28:00
いや、本人だから。
0301デフォルトの名無しさん2006/01/08(日) 23:23:09
Steeleさんはコンピュータ言語だけでなく、
自然言語にも精通していらっしゃるのですね。
0302デフォルトの名無しさん2006/01/09(月) 11:30:53
>>287
さすがに SBCL Win32 port がそんなにはやく安定するとは思えん.つか
CLISP でいいじゃんな.どうせなら ANSI CL 準拠のほうがいいと思うがなぁ.
GCL は配布物でかいし,本家の配布物ってまだ ANSI 互換モードがデフォじゃ
なかったような.
0303デェフォルトの名無しさん2006/01/09(月) 22:05:20
単に動けばいいのなら、CLよりSchemeのほうがよくない?
CLISPよりPetite Chez Schemeのほうが・・・
エディタならDrSchemeあるし。
あくまでWindows環境なら、って話ね。
WindowsでLISPでとなればSBCLははずせないんじゃないの?
0304デフォルトの名無しさん2006/01/09(月) 23:13:25
…いや CL の授業なんでないの?開発環境としては LispWorks Personal とか
Allegro CL のがいいような.インストールメチャかんたんだし,統合開発環境
こみだし.LispWorks Personal なんか授業で使うならいいと思うけどねー.

SBCL Win32 port は現段階,マージがはじまった段階で,そのあと残りの
ToDo を片づけていくっつーレベルなんで SBCL Win32 は Lisp マニア以外には
敷居高杉.すくなくとも 0.9.8.x のうちは授業で使う環境の選択肢には入れちゃ
ダメ.だから開発者もまだ実用は無理とゆってるのわけで…
0305デフォルトの名無しさん2006/01/09(月) 23:17:47
#!-win32 だらけだしなあ。
まだ sbcl-devel #lisp 参加者以外が使ってもしょうがないだろ。
0306デフォルトの名無しさん2006/01/12(木) 11:35:45
Schemeのsyntax-rulesと似たようなものを作ってみたいのですが、
不勉強なもので、よくわかりません。
gaucheのソースとか見てみたのですが、さっぱりで、、、。
macro.cあたりにまとまって書いてあるようなのですが。
パターン言語とかいうらしいのですが。
よい参考資料などありましたら教えてください。
0307デフォルトの名無しさん2006/01/12(木) 14:48:48
>>306
syntax-rulesで難しいのはむしろ健全性の方だと思うが、
パターンマッチが知りたいんだよね?
繰り返し (...) を除けばパターンマッチはそんなに難しくない。
アルゴリズムの入門書あたりに出てないかな。
健全性の方はWill Clingerの論文Macros That Workがいいよ。
0308デフォルトの名無しさん2006/01/12(木) 16:24:27
アルゴリズムの入門書の書名を具体的に教えて。勉強したい。
03093062006/01/12(木) 16:58:39
>>307
ありがとうございます。

まずは、パターンマッチから知りたいところです。
自分で調べてみて、xyzzy lisp programmingの
common lisp入門を読んでみてます。

http://www.geocities.jp/m_hiroi/xyzzy_lisp/abclisp22.html

SICPにも書いてあるようなのですが、難しく感じてしまって、、、。

健全性の方はWill Clingerの論文Macros That Workがいいんですね。
探してみます。きっと英語なんでしょうねぇ。先は長い。。。
0310デフォルトの名無しさん2006/01/12(木) 17:14:18
on lispの翻訳
ttp://user.ecc.u-tokyo.ac.jp/~t50473/
0311デフォルトの名無しさん2006/01/12(木) 17:17:36
知らんのだ。すまん。>>308
効率良くするのは難しいが、原理は簡単なんで、
入門書のアルゴリズムの練習問題にありそうだと思っただけ。
ざっと説明すると、パターン言語は(1)入力とパターンのマッチをかけて、
パターン中のパターン変数と入力との対応づけをつくる、(2)成功したら
テンプレートを走査してパターン変数を入力に置き換える、ということを
やってるだけだ。(続く)
0312デフォルトの名無しさん2006/01/12(木) 17:19:29
で、とりあえず単純なマッチと置き換えのコードを示しておくから
後は好きに拡張してくれ。シンボルは全てパターン変数として扱い、
シンボル以外のものは考慮してない。

(define (match template input)
(define (walk template input binding succ)
(cond
((null? template) (and (null? input) (succ binding)))
((symbol? template) (succ (acons template input binding)))
((pair? template)
(and (pair? input)
(walk (car template) (car input) binding
(cut walk (cdr template) (cdr input) <> succ))))))
(walk template input '() values))

(define (subst tree binding)
(cond
((pair? tree)
(cons (subst (car tree) binding) (subst (cdr tree) binding)))
((and (symbol? tree) (assq tree binding)) => (cut cdr <>))
(else tree)))

gosh> (subst '(d c b a) (match '((a b) (c . d)) '((1 2) (3 4 5))))
((4 5) 3 2 1)
0313デフォルトの名無しさん2006/01/12(木) 21:24:55
>>306
こないだC#で実装した(我流で)。
(define-syntax m (syntax-rules () ( (_ "constant" a (b (c ...)) ...) (a x (1 b ...) (c ...) ...))) というマクロがあり、
(m 1 (2 (3 4 5)) (a (b)) (x ())) というパラメータが渡されたとする。

マクロを解析すると、
パターン部は
((const "constant") (param a) (... (param b) (... (param c)))) というツリー構造になり、
テンプレート部は同じく
((param a) (var x) ((const 1) (... (param b)) (... (... (param c)))) となる。

パターンマッチはパターン部とマクロのパラメータを再帰的に比較すればよい。

適合するパターンが見つかったら、パラメータとパターンから
a:level0 data:1
b:level1 data:(2 a x)
c:level2 data:((3 4 5) (b) ())
という表を作り(このへんはGaucheのコメントを参考にしたような)、それをTemplate部に適用する

(param a) → テーブルからaの値を引いてくる。1を生成
(... (param b)) → ...(これの正式名称なんだっけ?)が出現したら、前述の表から……どうするんだっけ?
いま手元にソースがないので忘れたが、
b:level0 data:2
b:level0 data:a
b:level0 data:x
という3つの表を順番に生成して(param b)部に適用。
ネストした...も同様に再帰的処理して生成。
03143062006/01/12(木) 21:32:01
>>311 >>312
ほー。すごい。
schemeは素人なので、すぐわからないのですが、参考にさせてもらいます。

(subst '(d c b a) (match '((a b) (c . d)) '((1 2) (3 4 5))))
の意味は
((1 2) (3 4 5))を((a b) (c . d))にマッチさせて(d c b a)に変換するってことですよね。
((1 2) (3 4 5))は((4 5) 3 2 1)に変換されてると。
matchがマッチしたものを返して、substはmatchした結果を使って置き換えしてると。

ありがとうございました。
03153132006/01/12(木) 21:33:16
はいじにっくのほうだが、マクロによって生成されたシンボルにユニークなキーを付加してどうにかした。

(m1 a) → (m2 a x)
(m2 a b) → (let ((a 100)) b)
というマクロにおいて、

(m1 x) → (m2-1 x-0 x-1) → (let ((x-0 100)) x-1)
0316デフォルトの名無しさん2006/01/13(金) 02:06:46
パターンマッチに興味があるなら Unification で検索しる.
Common Lisp の cl-unification ライブラリのマニュアルと実装も参考になるお.
0317デフォルトの名無しさん2006/01/13(金) 10:11:28
UnificationならPrologだな
0318デフォルトの名無しさん2006/01/13(金) 11:30:54
でもここじゃ双方向unificationは必要なかろう。
03193062006/01/13(金) 11:50:09
>>313
いろいろ、具体的な解説ありがとうございます。
まだ、わかっていないのですが、参考にさせてもらいます。

>>315
その説明は考えてみても、よくわかりません。
(m1 a)を(m1 a x)と展開するマクロなのであれば、xは外のスコープから
データを持ってくるものなのじゃないかと思うので、
(m1 x)→(m2 x x)って変換されていい気がするのですが、、、。
(m1 b)→(m2 b x)なのですよねぇ。

はいじにっくのほうは、
マクロを呼んでいるスコープ内で使われている変数や関数名と
名前がぶつかった場合は、例えばxがぶつかったのであれば、
x-0などと言った風に名前をユニークにしてあげればいいって考えてました。

>>316 >>317
Unificationはとても面白そうなのですが、
マクロを作るのにはそこまで必要ではなさそうなので、
後で挑戦してみようと思います。
0320デフォルトの名無しさん2006/01/13(金) 20:22:32
Schemeって対話環境とファイルを読んで実行する場合とあると思うんですが、
ファイル読んで実行する場合、トップレベルの defineはあらかじめ分かるので
全体が letrecに入っている風に解釈してもいいでしょうか?
検索が必要なくなりますし、set!が無ければもっと最適化できそうな予感がするので。
0321デフォルトの名無しさん2006/01/13(金) 20:41:43
後からloadとかevalによる環境の置き換えを許さないのならね。
Stalinはそれを前提にプログラム全部を読み込んで最適化をかけるので
出てくるコードは激速らしい。
03223202006/01/13(金) 20:55:04
あと、
(define (f a b) (+ (g a) b))
なんて行があったとして、gがこの行以前に束縛されていて
この後変更されないことが保証されていれば最適化ができると思うのです。

(define (a f) (lambda (b) (f (+ 1 b))))
(map (a func) l)
なんて時は(a func)の返り値は実行時にコンパイルするんでしょうか?


手続きを束縛するシンボルを破壊的に操作することって
ほぼない上に最適化の邪魔になるからとても嫌なんですが。
0323デフォルトの名無しさん2006/01/13(金) 21:04:17
>>321
そうなんですか、あんまり一般的な最適化じゃないんですね。
loadは...手続きなんですね。#includeみたくマクロだったら良かったのに。
(eval '(define a e) (interaction-environment))
なんてしたらトップレベルが汚れちゃうんですね。こんなの使わないのに。
Schemeのなんでもありって仕様が最適化の邪魔になってる気がしてます。

>>322の「実行時にコンパイル」は「実行時に最適化」の間違いです。
0324デフォルトの名無しさん2006/01/13(金) 21:36:05
最適化のために仕様を逸脱します、てのは実装としては
ありなんじゃないかな。動作さえ明確に定義できれば。
0325デフォルトの名無しさん2006/01/14(土) 01:16:58
>>317
あれは組み込みでは…
でも Prolog はバックトラックも組み込みだしちょっと面白みがねー.
もっと別の探索手法がつかいたいとか,そーゆうレベルでいじりたいと
結局 Lisp で作っちゃうんだよな
03263152006/01/14(土) 02:05:27
>>319
(m1 a) → (m2 x a)
(m2 a b) → (let ((a 100)) b)
とゆうマクロがあったときに、(m1 x) → (m2 x x)と展開するとどうなるか。
(define x 200)
(define y 200)

(m1 x) → (m2 x x) → (let ((x 100)) x) → 100
(m1 y) → (m2 x y) → (let ((x 100)) y) → 200

はいじにっくじゃない!!!!!!ひどい!!!!
というわけで、「外から渡されたもの」と「自分のテンプレートにより生成されたもの」は区別しなきゃいけないのよ。
0327デフォルトの名無しさん2006/01/14(土) 02:21:07
>>326
>なんて時は(a func)の返り値は実行時にコンパイルするんでしょうか?
んなわけない。グローバル最適化とか考える以前にクロージャを含む言語の
コンパイルについて勉強すべし。

>手続きを束縛するシンボルを破壊的に操作することって
>ほぼない上に最適化の邪魔になるからとても嫌なんですが。
目的による。Lisp系言語の場合、インタラクティブな開発時には
ひとつの関数定義を修正してリロードして、というのを繰り返すから、
グローバルな手続きが再定義できるのは便利でもある。
デバッグが済んだ段階で「全部constantと考えて最適化」という
オプションはあってもいい。

ただ、歴史がある商用のLisp処理系でさえそういうことを重視してないのは
何故だかは考えて見る必要はあるだろうね。
単なるインライニングくらいじゃそんなに速くならないんよ。
型推論して実行時型チェックを減らせるとかなり効果があるけどね。



0328デフォルトの名無しさん2006/01/14(土) 11:51:22
改行が多すぎますって言われて全部消えた...

>>327
>んなわけない。グローバル最適化とか考える以前にクロージャを含む言語の
>コンパイルについて勉強すべし。
内部でクロージャを生成し、それを返す、又は set!する手続きの場合
一般的に環境をスタックからヒープにコピーする必要があると思うんですが
あらかじめ以降の引数などをヒープにつくれば後の環境のコピーが省けるかなあ
と思いました。
リストが与えられた時に先頭がどういう手続きかあらかじめ分かっていれば
その条件分岐もいらないですし、組込みの手続きとの条件分岐もいらない気がします。
動的にクロージャが生成され((a func)みたいに)、変更されないことが保証された上で
何度も使われる((map (a func) l)みたいに)前にコード化すれば実行中の条件分岐が
なくなっていいかなあと思いました。妄想ですが。
SECDマシーンみたいのを想像しているので間違っているかもしれません。
0329デフォルトの名無しさん2006/01/14(土) 11:59:45
>>327
>ただ、歴史がある商用のLisp処理系でさえそういうことを重視してないのは
>何故だかは考えて見る必要はあるだろうね。
>単なるインライニングくらいじゃそんなに速くならないんよ。
>型推論して実行時型チェックを減らせるとかなり効果があるけどね。
単なるインライニングならトップレベルを letrecに入れるだけなので
ほとんど変わらないでしょうね。
型推論は全体が letrecに入っていると思えばできるのかも。もしくは Scheme->Ocamlとか。
Ocamlの場合、関数定義のなかに未知のシンボルが現われるとエラーなので
インタラクティブに型推論ができるのかもしれませんが、Schemeだと難しそう。
また、
# let f x = x;;
# let g x y = x + y;;
# let h = ref f;;
# !h = g;;
This expression has type int -> int -> int but is here used with type
int -> int
となりますし。開発中とはいえ手続きの型まで変えることはあまりないと思いますが。

開発言語と実行言語に分けて、実行言語は制限つけて高速コードにコンパイルと
いう風にすれば Schemeが天下とれませんかね?
03303062006/01/14(土) 13:15:34
>>326
うー、わかったようなわからないような。

(m1 x) → (m2-1 x-0 x-1) → (let ((x-0 100)) x-1)
これが、
(m1 x) → (m2 x-0 x) → (let ((x-0 100)) x)
って話ならわかるような気がするんですが、、、。

scheme理解できてないからかなぁ。。。

例がよくわからないので、すいませんがcで書きますと

#define swap(a,b) {int tmp=a;a=b;b=tmp;}
int x = 1, y = 2; swap(x,y);
=> {int tmp=x;x=y;y=tmp;} OK

int a = 1, tmp = 2; swap(a,tmp);
=> {int tmp=a;a=tmp;tmp=tmp;} だめ

となって、うれしくないのがはいじにっくでないと
で、その場合は
{int tmp1=a;a=tmp1;tmp=tmp1;}
として解決してくれれば、はいじにっくだとそういう話
以外に何かありそうなのですが、わからなくて、、、。すいません。
0331デフォルトの名無しさん2006/01/15(日) 02:46:37
>>329
> 開発言語と実行言語に分けて、実行言語は制限つけて高速コードにコンパイルと
> いう風にすれば Schemeが天下とれませんかね?
それは CL っぽく色々 declare とかコンパイラマクロをぶち込むってのじゃ駄目なのん?
■ このスレッドは過去ログ倉庫に格納されています