5ちゃんねる ★スマホ版★ ■掲示板に戻る■ 全部 1- 最新50  

■ このスレッドは過去ログ倉庫に格納されています

LISP Scheme Part2

1 :デフォルトの名無しさん:01/10/09 08:39
lambdaさんはこちらへどうぞ

前スレ
http://piza2.2ch.net/test/read.cgi/tech/987169286/

2 :デフォルトの名無しさん:01/10/09 19:53
□参考リンク□

日本Lispユーザ会(日本語)
http://jp.franz.com/jlug/index.html
ここにかなりの情報があります。

プログラミング言語Scheme(日本語)
http://www.sci.toyama-u.ac.jp/~iwao/Scheme/scheme.html
Schemeの人はまずここを見ましょう。

Lisper への道(日本語)
http://www.geocities.co.jp/SiliconValley-Oakland/1680/rakup.html
判りやすいLISP入門サイト

Schemeへの道(日本語)
ttp://www.stdio.h.kyoto-u.ac.jp/~hioki/gairon-enshuu/SchemeNotes/scheme.html

Practical Scheme(日本語)
http://www.shiro.dreamhost.com/scheme/index-j.html
「普通のやつらの上を行け」など、興味深い文書があります。

SICP(英語)
http://mitpress.mit.edu/sicp/full-text/book/book.html
「計算機プログラムの構造と解釈」の原書です。
全てオンラインで読めます。

Scheme Hash(英語)
http://okmij.org/ftp/Scheme/index.html

John McCarthy's Home Page
http://www-formal.stanford.edu/jmc/
LISPの生みの親、J・マッカーシーのページだそうです。

お隣りのプログラマ板のLISPスレです。
http://mentai.2ch.net/test/read.cgi?bbs=prog&key=963134110

3 :デフォルトの名無しさん:01/10/09 19:54
□仕様書関係□

Common Lisp the Language, 2nd Edition(英語)
http://www.cs.cmu.edu/afs/cs.cmu.edu/project/ai-repository/ai/html/cltl/cltl2.html
CommonLispの仕様書です。

アルゴリズム言語Schemeに関する第五改訂報告書 R5RS(日本語)
http://www.sci.toyama-u.ac.jp/~iwao/Scheme/r5rsj/html/r5rsj_toc.html
日本語訳はここ以外にもあるそうです。

Scheme Requests for Implementation SRFI (英語)
http://srfi.schemers.org/

4 :デフォルトの名無しさん:01/10/10 04:05
>アルゴリズム言語Schemeに関する第五改訂報告書 R5RS(日本語)
>http://www.sci.toyama-u.ac.jp/~iwao/Scheme/r5rsj/html/r5rsj_toc.html

この犬飼訳はひどいよ〜。

proper tail-recursion 「正しい終端再帰」(「真の」だろ)
conditional expression「条件節」(条件式だろ)
binding construct「バインディング構成手続き」(「バインドする構文」だろ)
exactness「完全性」(「正確さ」だろ)
formal syntax and semantics「意味論と言語仕様」(をいをい‥)

かといって村上訳
http://www.biwa.ne.jp/~mmura/scheme/tspl.html#r5rs
もひどいがなー。まだ犬飼訳よりましだろー。

5 :山神竜一郎:01/10/11 13:17
マ板のLISPスレから合流しました。よろしゅうに。

6 :Lisp板の753:01/10/11 17:07
協調性の必要性を、感じてやっぱり合流する事にしました。
よろしくお願いします。

7 :デフォルトの名無しさん:01/10/11 20:41
C言語でLISPを作ってるんですが、リストに対して、効率的なhash値を
得る事はできないでしょうか?最初はリストのポインタのアドレスをそのまま
hash値にすれば速いかな、と思っていたんですが、後々gcを搭載する時に、
ポインタ値の比較をやっていたのでは、移動ができない事に気付きました。
(マークスイープのgcならこれでもいいんですが。)
シンボル探索を線形探索→hash(チェイン法)にしたら、とんでもなく
速くなったので、リストに対してもできないものか、と考えています。
carやcdr方向の長さとかで区別するしか無いでしょうか?

8 :デフォルトの名無しさん:01/10/12 01:05
> (defmacro prove (wff)
`(wang (addr (car ,wff) (line 0 nil nil nil nil)))
)
. reference to undefined identifier: defmacro
> (define-macro prove (wff)
`(wang (addr (car ,wff) (line 0 nil nil nil nil)))
)
define-macro: malformed definition
>
結論!!Ruby戦隊に荒らされて騙されたなり
>>7さん
クダ−方向のってよく解りません
cdr vector???

9 :デフォルトの名無しさん:01/10/12 01:21
>>8

XLISP-PLUS version 3.04
Portions Copyright (c) 1988, by David Betz.
Modified by Thomas Almy and others.
XLISP-STAT Release 3.52.14 (Beta).
Copyright (c) 1989-1999, by Luke Tierney.

には、defmacroがありますが…

10 :Lispで方言はもうやめよう委員会:01/10/12 01:33
>>9
すいません今Schemeにはまってます

11 :デフォルトの名無しさん:01/10/12 02:07
>>10
ああ、

> 今Stuart C. Shapiro著
> 松田利夫訳のLISPによる人工知能の基礎技法
> の序章を、目を皿の様にして読んでるのですが
> 共立出版の本て、どれも解りずらいです。

は、Scheme(やCommon Lisp)で頑張った方がいいと思う。

たしか、これSNOBOLやPLANNER何かも使う本だよね。

12 :Lispで方言はもうやめよう委員会:01/10/12 02:37
>>11
そうです。
SBOBOL4とMICROPLANNERです。
あとLispです。
なんか表紙が赤い本です。

13 :名無しλ:01/10/12 02:53
>>7
GCのたびにハッシュ表をスキャンして、GCで
コピーされたハッシュキーだけハッシュしな
おすのが定石なり。

キーが長寿命領域に逝ってしまえばrehash回
数は激減するのでだいじょうぶ。

#しかし厨房が増えたな…fexprなんてコン
#パイラを使わない時代の化石だろー

14 :デフォルトの名無しさん:01/10/12 03:20
>>13
> #しかし厨房が増えたな…fexprなんてコン
> #パイラを使わない時代の化石だろー

ん? lambdaに&rest、&optionalがない、macroがない時代の化石、でしょ?

それに、FEXPRを使っている本のprogramを動かしてみたいようだから仕方がないよ。
# Winstonの"LISP"という手もあるが…

15 :名無しλ:01/10/12 04:08
>>14
そういやlexprなんてのもあったね。&restが
あれば不要だが。

fexpr使っちゃうとコンパイル不可なのが欝。

16 :中年の厨房:01/10/12 06:28
>>15
lexprの解説きぼんぬ
       ↑
      ここ風

17 :デフォルトの名無しさん:01/10/12 06:56
http://homepage2.nifty.com/tamitu/qa2.lsp
このプログラムのその後の経過についてご存知の方
いますか?

18 :デフォルトの名無しさん:01/10/12 07:07
> (qa)
Type HELP for help.


Assert --(I love ya)

Assert --question

Question --(we love fuck)

Clause 1
(I LOVE YA) Clause 2
(OR (NOT (WE #:G1 FUCK)) ($SUCCESS$ (WE #:G1 FUCK))) Resolution
(OR ($SUCCESS$ (I LOVE FUCK)))

($SUCCESS$ (I LOVE FUCK))
Enter QUIT to quit, MORE for more solutions --
動かし方はこんな感じです。

19 :名無しλ:01/10/12 09:34
>>16
lexprって、引数が普通に評価して渡される、
可変個引数の関数のこと。MacLisp。
(DL LIST (X) X)
みたいな感じ。(Xのまわりのカッコは確か
要ったと思う。)

20 :17:01/10/12 12:41
exprも引数を評価してから関数に渡されるけど
引数の数は固定って事はlexprはexprよりも高機能って事ですね?

21 :デフォルトの名無しさん:01/10/12 12:53
ただ、>>15が言うように、
コンパイルしても、引数へのアクセスがスタックポインタ+オフセットにならないわな。
引数列をリストで渡して貰うわけだから。セルも消費するし。

まあ、可変個引数にしたい場合、(Lisp流儀だと)仕方がないわけだけど。

高い低いというより目的に合っているかどうかだな。

22 :デフォルトの名無しさん:01/10/12 13:12
なるほど
コンパイルして実行してみたらスタックエリアオーバーフロウ
みたいな?

23 :7:01/10/12 13:13
>>13
参考になりました。
やっぱりポインタ比較が速いですよね。

24 :デフォルトの名無しさん:01/10/12 13:35
>>23
どうやったらメモリー馬鹿食いしないかも
考えておいて

25 :デフォルトの名無しさん:01/10/12 19:07
>>24
はたして、LISPは言われている程にメモリを馬鹿食いするんでしょうか?
データ=コードという事実や、そのほとんどがリストなので、BASICなど
に比べるとやはり・・、ということになるんでしょうか。
(LISPもコンパイルすれば状況は変わると思いますが。)

26 :デフォルトの名無しさん:01/10/12 19:26
します
XlispをPC9801F2に移植した事があるけど
あっと言う間にビデオRAMまで住所が降りて画面が
真っ赤になった事があります。
ただTurbo C2.0でコンパイルしたら走ったんで
移植とは言えないかも知れないけど・・・

27 :デフォルトの名無しさん:01/10/12 22:17
>>26
DOSの頃の話?
>あっと言う間にビデオRAMまで住所が降りて画面が
こういうのって自然に起きるものなのかなあ・・・

28 :26:01/10/12 22:28
>>27
intel 8086でWindowsが走る訳無いじゃん
疲れたので今日からこっち行く。
http://www.rkmath.rikkyo.ac.jp/~kida/ubasic.htm
自然に起きるも何もソフトウェア工学ではLispは化け物だよ。

29 :27:01/10/12 22:34
>>28
ただ単に暴走してるだけなんじゃないのかなぁ?、って事なんだけど。
なんでWindowsの話?

30 :デフォルトの名無しさん:01/10/12 23:18
シンプルデザイン(Simple Design)
いつでもシステムは出来る限りシンプルに設計されるべきだ。余分な複雑さは見つけ次第取り除かれる。

リファクタリング(Refactoring)
2重コードを取り去り、コミュニケーションを改善し、単純化し、柔軟性を加えるために、プログラマは、システムの動作を換えることなくシステムを再構成する。

31 :デフォルトの名無しさん:01/10/13 01:00
>>27
バカだなお前
回線切って考えてから
首吊って氏ね

32 :デフォルトの名無しさん:01/10/13 01:06

       / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄\
.∧_∧  | >>31 Ruby厨な人さぁ こんなレスばっかりしてるから |
( ´∀`)< 厨房って言われちゃうんだよ                |
( ∧∧ つ >―――――――――――――――――――――‐<
 ( ゚Д゚) < おまえのことを必要としてる奴なんて Ruby使いにすら |
 /つつ  | いないんだから さっさと回線切って首吊って氏ね   |
       \______________________

33 :デフォルトの名無しさん:01/10/13 04:42
>>26
xlispって(藁
すぐxschemeになったよね。xlispは最初だけでしょ。
そういう腐ったOS上の太古の処理系のチェックが甘かっ
たからって何で「Lispはメモリを馬鹿食いします」に
なっちゃうわけぇ?

SunのJava x86でconsセル表現すると、32バイト必要。
Rubyだと20バイト。Lispなら8バイト。

で、U-BASICでconsセル表現するにはどうやるの?
何バイトいるの? (そもそも出来ないんでは(藁))

34 :デフォルトの名無しさん:01/10/13 05:07
Assembler debuger で Xlisp 走らせて^o^/
00 00 00 00 00 00 00 00か
FF FF FF FF FF FF FF FFしか
入ってないはずのメモリーの住所が文字列だらけに
なったよ。っとっとっと 止めないでくれ さくら!
お兄ちゃんはね UBASICの世界へ旅立つんだ〜

35 :デフォルトの名無しさん:01/10/13 05:08
(define call/cc call-with-current-continuation)
(define v 5)
(call/cc (lambda(x) (set! cc x) v))
(set! v (+ v 1))
(cc v)

どうしてこういうソースで無限ループに陥らないんですか?
(cc v)を評価した結果、そのまま進むとまた(cc v)に来ると思うんですが?

36 :デフォルトの名無しさん:01/10/13 05:23
   ∧_∧  / ̄ ̄ ̄ ̄ ̄
  ( ´∀`)< 再帰処理したいのかモナー
  (    )  \_____
  | | |
  (__)_)

37 :デフォルトの名無しさん:01/10/13 06:14
>>35
ちょっと待ってね今リストをコピペしたとこ

38 :デフォルトの名無しさん:01/10/13 06:33
>>35
(( ノ゚Д゚)(set! cc x)) てんとう虫出るぞ ゴルア
set!: cannot set undefined identifier: cc
>

39 :デフォルトの名無しさん:01/10/13 06:52
>>35
わしはやっぱりUBASICに帰るのだ
あとは名無しλさんとか、他の天才さん達にまかせるのだ
これでいいのだ

40 :デフォルトの名無しさん:01/10/13 07:18
>>33
XLisp-statは今統計解析で大活躍なのだ。
それよりJavaなんてトロ臭いもの本気でこれからも使って
行こうと思ってるのか?
さあ 答えるのだ。

41 :デフォルトの名無しさん:01/10/13 10:41
consセルは32bit環境で素直に作ると、car(4)/cdr(4)/識別子(1〜4)で、
少なくとも9〜12byteは必要でしょう。
8byteで済むっていうのは、ポインタに何か細工してるか、
識別子のテーブルを別に作ってるんでしょうね。

42 :デフォルトの名無しさん:01/10/13 10:44
>>35
(define cc '適当な初期値)
を忘れてる

43 :デフォルトの名無しさん:01/10/13 10:57
>>35
トップレベルじゃなくて、関数の中でやってみれば?
(define (f)
 (define cc '())
 (define v 5)
 (call/cc (lambda(x) (set! cc x) v))
 (display v)(newline) ;チェック用
 (set! v (+ v 1))
 (cc v)
)
(f) ;無限ループ

44 :デフォルトの名無しさん:01/10/13 11:02
letでもいいと思うけど
(let ((cc '())(v 5))
 (call/cc (lambda(x) (set! cc x) v))
 (display v)(newline)
 (set! v (+ v 1))
 (cc v)
)

45 :デフォルトの名無しさん:01/10/13 11:58
10 GOSUB 42 : PRINT "When I said Lets do it again,
He told me Thanks but no more for me." : GOSUB 43 : GOSUB 44 : PRINT "カコイイ"

46 :デフォルトの名無しさん:01/10/13 12:24
>>41
Xlisp-statのソース落ちてるから自分でヤホー検索して拾って調べるのだ。

47 :35:01/10/13 12:32
>>38 >>35
あ、そうですね(^^;

>>43 >>44
無限ループがしたいわけじゃないのです(^^;
call/ccの動作を知りたかったのです。

48 :Ruby初心者:01/10/13 12:34
Schemeで実用的なアプリケーションなんか作れないだろ。
いまどきSchemeなんて時代遅れ。

49 :デフォルトの名無しさん:01/10/13 12:37
   ∧_∧  / ̄ ̄ ̄ ̄ ̄
  ( ´∀`)< >>48 オマエモナー
  (    )  \_____
  | | |
  (__)_)

50 :デフォルトの名無しさん:01/10/13 12:41
>>48
ここはRubyなんてやってる超初心者の来る所では無いのだ。
己の恥に、気付く前に退散しろなのだ。

51 :Ruby初心者:01/10/13 12:43
違いますか?
じゃあ、実用的なアプリケーションを挙げてみてください。
何もないでしょう(嘲笑)

52 :Ruby初心者:01/10/13 12:49
Schemeごときが「プログラミング言語」って呼ばれちゃいけない、
と思うんですよ。

53 :デフォルトの名無しさん:01/10/13 13:04
>>17を拾ってXlisp-statで実行してみそ
Schemeは方言がきついので貴方にScheme上で>>17のソースを
実行するのは無理。

54 :デフォルトの名無しさん:01/10/13 13:07
Scheme自体が、すでに実用的なのだが何か?

55 :デフォルトの名無しさん:01/10/13 13:09
放置できない人はアホ。ウンコ。鼻毛。エスパー伊東。

56 :Ruby初心者:01/10/13 13:09
言語自身が実用的ってどういう意味ですか???

57 :デフォルトの名無しさん:01/10/13 13:15
>>Ruby初心者
今A.Iダッチワイフちびオメコちゃんのプログラムを
DrSchemeで書いてるから、もうちょっと待ってね!
>>55
放置しちゃ可哀想でしょ?
折角Schemeに嫉妬してるんだから・・・

58 :デフォルトの名無しさん:01/10/13 13:18
>>53
http://homepage2.nifty.com/tamitu/qa2.lsp
ってLISPのコードじゃん。
Schemeコードに変換するのはそんなに難しくはないけど。

59 :デフォルトの名無しさん:01/10/13 13:21
反論の余地が大きすぎて何を言ったらいいかわからないので放置
ってわけでもない人は修行が足りません。

60 :デフォルトの名無しさん:01/10/13 13:24
>>58
やってやって♪そしてここにコピペして〜
今Schemeやってる暇無いのよ(泣)
早くSchemeに本格以降したいです。

61 :デフォルトの名無しさん:01/10/13 13:25
Schemeの開発こそ、コンピュータ・サイエンスの典型的なセンスの
一つではないかと

62 :60:01/10/13 13:28
>>58
ソース結構でかいからコピペは無理なり
どっかにアップロードして下さい。

63 :60:01/10/13 13:31
>早くSchemeに本格移行したいです。
御変換すいません。

64 :デフォルトの名無しさん:01/10/13 13:34
>>61
by はぎゃ先生

ですな(ニヤリ

65 :デフォルトの名無しさん:01/10/13 13:35
>>61
LispからSchemeへの移行は、ある意味>>30を実現している。

66 :デフォルトの名無しさん:01/10/13 14:10
>>64
はぎゃ先生って誰?解説きぼんぬ

67 :デフォルトの名無しさん:01/10/13 14:42
>>66
http://nicosia.is.s.u-tokyo.ac.jp/welcome-j.html
>>61は上のページにある"H君への手紙: 天才."からかと。

http://www.google.com/search?q=cache:UMgsoaahNsA:nicosia.is.s.u-tokyo.ac.jp/welcome-j.html
ついでにここも見るよろし。

萩谷昌巳は湯淺太一と一緒にKCL(GCL)を作った人でもある。

68 :デフォルトの名無しさん:01/10/13 16:05
>>17
ところでこれ、なんのプログラムですか?

69 :デフォルトの名無しさん:01/10/13 16:24
>>68
言語意識のシミュレーションの基礎研究かと思われ。
Assertから(This is a pen)
と入力して
Questionと括弧を付けずにタイプして下さい。
それから(I love you)
と打って下さい。
パソちゃんは、知らない事にはI don't know ^^;
と答えるはずです。
でも
(Is this a pen)
と聞いてあげて下さい。

むにゃむにゃ

70 :デフォルトの名無しさん:01/10/13 16:36
>>68
Assert modeではコンピューターに与える知識としての
言葉は単語1個に付き1回がコツです。
wasだろうがisだろうが複数回定義するとG1,G2と
表示されコンピューターが何を言っているのか
わからなくなります。
baseで確認しながら
helpをタイピングすると一応ヘルプ画面もあります。
>>67
Thanx!

71 :デフォルトの名無しさん:01/10/13 16:45
SCHEMEって名前はねー。

MITのAI LAB.で作る言語は
CONNIVER とか PLANNER とか
「考えるもの」系の名前が
伝統だったんで、
「SCHEMER」とつけようとし
たら、ファイル名の制限
(6文字+3文字)でSCHEMEに
なっちゃったってスチール
君が言ってた。

72 :プレゼントのお知らせ♪:01/10/13 16:57
>>58 >>68
Schemeに移植に成功したらmp3全部持っていっていいですよ^o^/
http://homepage2.nifty.com/tamitu/
>>71
なんて発音するんですか?

73 :デフォルトの名無しさん:01/10/13 17:03
とりあえずシェーマ−だと思う。
叩かれ覚悟のカキコ!

74 :デフォルトの名無しさん:01/10/13 17:06
>>71
CONNIVER も PLANNER も 6 文字超えてるやん…

75 :デフォルトの名無しさん:01/10/13 17:29
いい つっこみだけどMITとPLTの現場環境が違うとか?
なんで みんなsageてんの?

76 :デフォルトの名無しさん:01/10/13 17:53
解った^お^ 宝石君が来るからだ

77 :デフォ@Part2は進むの早いな:01/10/13 18:13
Scheme暦2ヶ月の前スレ901です
Schemeのことをもっと知るために、前スレ最後の方で挙がってた
「Schemeの過去・現在・未来」前後編をコピってきました。
根底に、オブジェクト指向的考え方があったとは…
意外でもあり、また、当然のような気もしました。

あと、>>74ですが、
www-2.cs.cmu.edu/Groups/AI/html/faqs/lang/scheme/part1/faq-doc-14.html
を読むと、PlannerやConniverはPLNRとかCNVRと省略されてるみたいです。
確かに、これじゃ、読めないわな

78 :デフォルトの名無しさん:01/10/13 18:38
>>77
おー、そういやガッコのディスクあさってたら
PLNR.X っていうファイルがあったけどあれは
Planner言語ダッタのカー

SHRDLUっていうディレクトリの中にあった。

79 :デフォルトの名無しさん:01/10/13 19:06
SHRDLU、>>11に出てるよ。

80 :デフォルトの名無しさん:01/10/13 19:53
他スレでこういう書き込みがありました。
http://piza2.2ch.net/test/read.cgi/tech/1002377328/117
どう思いますか?

81 :デフォルトの名無しさん:01/10/13 19:56
GEB本にも出てたな。
SHRDLUよ、人の望みの喜びよ、ってか。

http://hci.stanford.edu/~winograd/shrdlu/
からダウンロードできるよ。

それよりどこかにGEDANKEN落ちてないか?

82 :DrScheme歴8日:01/10/13 20:18
>>44
をコピペしたらDrSchemeで走っちゃった^^;
HDがカラカラ言ってる
誰か止め方教えて

83 :DrScheme歴8日:01/10/13 20:25
Ctrl+Alt+Deleteで逝ってよし
始めて走った

84 :DrScheme歴8日:01/10/13 20:34
Allegro アンインスト決定!

85 :DrScheme歴8日:01/10/13 21:06
>>80
放置
>>81
いや〜んProxyはねてるぅ
GEDANKENって何ですか?

86 :デフォルトの名無しさん:01/10/14 00:07
>>85
ドイツ語です。

87 :85=86:01/10/14 00:14
ジサクジエンです。
GEDANKENて言うLisp関連の何かがあるのかと思いました^^;

88 :デフォルトの名無しさん:01/10/14 00:53
ちょっとageさせて下さい。
無限ループの終了方法が良くわかりません。
要操作方法のヘルプ日本語化→DrScheme

89 :デフォルトの名無しさん:01/10/14 01:05
>>44の様な処理をブラウザ立ち上げたまま
行うとDrSchemeの窓も閉じなくなる程OSが重たくなります。
かなりのハードウェアリソースを消費していた様です。

90 :デフォルトの名無しさん:01/10/14 01:08
おれの自作SchemeではDOS窓で軽快に無限ループに陥ってるよ。
終了はCtrl+C

91 :Tamitu:01/10/14 01:31
>41
別にWindowsで走って更にMacで走ってUNIXでまでも走る
必要無いからじゃないの?
XLispにしろDrSchemeにしろ ある目的の為に世界で一番優れた
アルゴリズムを見つけ出すのが目的の1つな訳だから・・・
javaやってる人は、ネットしかしない人を、相手にしてあげて。
>>90
Uploadして直リンは、礼儀かも

92 :デフォルトの名無しさん:01/10/14 01:42
>>91
デバガとかインタフェースがなってないから無理よ。
まだ自己満足的な実験対象でしかないんで。
今の所8086でも動く。
気が向いたら公開するかも。

93 :デフォルトの名無しさん:01/10/14 02:01
>>89
Windowsはschedulerがあまり賢くないから、
暴走するthreadがCPUを独占する事が良くある。

;; 嘘みたいな話だけど、priorityが固定なのだ…
;; スレ違いでsage

94 :デフォルトの名無しさん:01/10/14 02:26
>>41
Lispのconsセルはポインタ2つきっかりになるのが普通だ
よ。Javaとかと違って型の種類が固定だから、ポインタの
下3ビットとかに型情報をエンコードする。特にconsセル
と小さい整数あたりは最も効率よい表現を割り当てる。

95 :デフォルトの名無しさん:01/10/14 02:38
>94
普通なのか?
移植性は?

96 :デフォルトの名無しさん:01/10/14 03:42
ポインタの下3ビットって・・・・
そんなことしたら値が参照できなくなるだろ

97 :デフォルトの名無しさん:01/10/14 03:53
>>94
オブジェクトの配置を8バイトアラインメント前提にして、
下3bitマスクすれば、まあできそうだけど、実際そういう事
してる処理系あるの?
システムからメモリブロック受け取って、その開始アドレスが境界
とずれてたら、使用アドレスを調整(±8byte)したりするのかな?
ca...drとか、1参照毎にマスク計算入るから遅くなりそうだけど。

98 :BASICER:01/10/14 04:01
>>92
PC9801F2でも動くのだな
Xlispに喧嘩を売るのだ
どれどれ見せなさいなのだ
自己満足は他己満足なのだ

99 :デフォルトの名無しさん:01/10/14 04:06
>>97
マスクなんかしないって。オフセットを引いてインデック
スモードでアクセスするだけだから、遅くならない。
RISCだと、同時に型チェックも兼ねられる(オフセットが
合ってなければバスエラーになる)。

「下2ビットゼロ」はfixnumとしておけば、整数演算も速
くて便利。配列アクセス時もシフト不要。SPARCの命令セッ
トはこれを考慮してる(taddcc命令は、下2ビットがゼロで
ないとトラップが起きる)。

100 :デフォルトの名無しさん:01/10/14 04:18
>>99
CISCだとマスクいるだろ。RISCでも、バスエラーでチェックできるのは下2ビッ
トだけと思われ(下3ビットはだめだろ)。

>>95-97
これは「タグ」と言って動的型の言語だと常識だよ。ポインタたぐらないと型
チェックできないような処理系はおもちゃ。

101 :デフォルトの名無しさん:01/10/14 04:31
>>98
>オフセットを引いてインデックスモードでアクセス
って、マスクとるのと同じ事だと思うんですが。
できればC言語レベルでどうやるのか簡単に書いて欲しいです。
いまいちのみこまません。
typedef struct _cell {
 struct _cell *car;
 struct _cell *cdr;
} cell;
#define car(p) ((p)->car)
#define cdr(p) ((p)->cdr)
こんな感じで。

102 :101:01/10/14 04:32
>>99 でした。

103 :99:01/10/14 04:44
>>101

typedef union _obj {
 struct _pair *pair; struct _symbol *symbol; ... } obj;
typedef struct _pair { obj *car, *cdr; } pair;

#define TAGOF(x) ((unsigned long)(x)&0x3)
#define IS_FIXNUM(x) (TAGOF(x)== 0)
#define IS_PAIR(x) (TAGOF(x)== 1)
#define IS_SYMBOL(x) (TAGOF(x)== 2)
#define IS_MISC(x) (TAGOF(x)== 3)

#define CAR_UNSAFE(x) (*(obj*)(((char*)(x))+offsetof(pair,car)-1))
#define CDR_UNSAFE(x) (*(obj*)(((char*)(x))+offsetof(pair,cdr)-1))

#ifdef HARDWARE_TYPE_CHECK
#define CAR(x) CAR_UNSAFE(x)
#define CDR(x) CDR_UNSAFE(x)
#else
#define CAR(x) (IS_PAIR(x)?CAR_UNSAFE(x):type_error())
#define CDR(x) (IS_PAIR(x)?CDR_UNSAFE(x):type_error())
#end

>>100
>これは「タグ」と言って
正確には「tagged pointer」な。

ちなみにオブジェクト側に型情報書いといても(object
tag)ca..drとかの時には毎回チェックがいるぞ。もっと遅
くなる。

104 :96:01/10/14 04:46
>>100
あ、もしかして自分でヒープマネージャを作って、
alignmentをあわせるようにするってことですか?

普通にnew/malloc使うこと考えてた・・・

105 :99:01/10/14 04:50
まちがいた。

typedef union _obj {
 struct _pair *pair; struct _symbol *symbol; ... } obj;



typedef union _obj {
 struct _pair pair; struct _symbol symbol; ... } obj;

のまちがい。すまそ。

106 :101:01/10/14 04:51
>>103
ありがとうございます。
「マスク取る方法」ってのはこんなのを想像してましたが、結構近かった様です。
typedef struct _cell {
 struct _cell *car;
 struct _cell *cdr;
} cell, *cellptr;
typedef int p2i_t; //ポインタと同じサイズの整数型
enum {TYPE_ATOM, TYPE_CONS}; //型
#define flags 7 //下位3bit 1bit=型 残り2bit=gcとか、他の用途
#define type_flag 1 //cons or atom
#define mask (~flags)
#define typeof(p) ((p)&type_flag)
#define car(p) ((cellptr)((p2i_t)((p)->car)&mask))
#define cdr(p) ((p)->cdr)
#define atomp(p) (typeof(p) == TYPE_ATOM)
#define consp(p) (typeof(p) == TYPE_CONS)

107 :99:01/10/14 04:58
>>104

んー、cons呼ぶたびにmalloc(sizeof(pair)してちゃ遅す
ぎる(しメモリもムダだ)と思うぞ。mallocはいろんな大き
さ扱うためのオーバーへッドがあるから。

最近の処理系だとこんなじゃないか?

#define SET_TAG(x,tag) ((object *)((unsigned long)(x)+(tag)))

obj *cons(obj *car, obj *cdr)
{
 obj *value;
 if (heap_ptr + sizeof(pair) > heap_limit) {
  gc();
 }
 value = heap_ptr;
 heap_ptr += sizeof(pair);
 value->pair.car = car;
 value->pair.cdr = cdr;
 return SET_TAG(value, CONS_TAG);
}

まあ、コンパイルコードだと、上をインライン展開してあ
るだろうが…

108 :BASICER:01/10/14 04:59
>>99
CISCとRISCね
はは〜ん だからJavaは馬鹿トロイのか

109 :96:01/10/14 05:05
>>107
ありがと。根本的に自作Schemeを書き換える必要が出てきました。
遊び処理系だから別に良かったんですが、、、
consセルで16バイト(car/cdr/type/virtual) しかもその都度newしてたんで。

110 :101:01/10/14 05:08
よく考えたら、わざわざマスク取る時にcons->carにする
必要無かった、、。
>103
#define CAR_UNSAFE(x) (*(obj*)(((char*)(x))+offsetof(pair,car)-1))
なんでここで-1してるの?って思ったら、
pair型を前提としてるからか。

111 :100:01/10/14 05:09
>>107
heapの最後のページをmprotect()で書き込み禁止にしとけば、if文は不要と思
われ。(RISCのバスエラー使うぐらいなら、これも使ってよいでしょー。)

consは、だからコンパイルすると3-4命令くらいかな。(heap_ptrは普通レジス
タにグローバルに割り当てる。)

112 :デフォルトの名無しさん:01/10/14 05:17
>>108
さすがBASIC厨房。

Javaのような静的型付き言語だと、ダウンキャスト時以外
型チェックの必要がないのだよ。だからtagもあまり重要
でない。

>>109
virtualでやるのはそんなに悪くない選択だぞ。ただfixnum
演算でゴミが出まくるようだと、ちとつらいが...

113 :デフォルトの名無しさん:01/10/14 05:28
なるほどねえ。バイトアラインメントを利用するのか。
consの使用量が2/3(9〜12byte->8byte)になるなら、
やる価値あるかも。

114 :デフォルトの名無しさん:01/10/14 05:35
>>112
>virtualでやるのはそんなに悪くない選択だぞ。

でもnewだと遅いよね。
Pairクラスのvoid *operator new(size_t)をoverrideして、自家製の
アロケータに入れ替えちゃうのが良いと思われ。

>ただfixnum演算でゴミが出まくるようだと、ちとつらいが...

±1000くらいはあらかじめ割り付けて、配列に取っとく。
結果がその範囲なら、割り付けずに配列の中の値を返す。

115 :96:01/10/14 05:35
んー、CISC(x86)onlyだったら、8バイトalignで、下3bitにTAG付けるのがベストかな。

116 :デフォルトの名無しさん:01/10/14 05:46
なんつーか、LISPerは処理系の実装テクまで話し合うのねん。

117 :96:01/10/14 05:47
3bit すべて型情報 でGCが stop and copy か、
2bit 型情報で、1bitGCに割り当ててGCをmark-and-sweepにするか。

118 :デフォルトの名無しさん:01/10/14 05:56
>>117
mark and sweepでも、オブジェクト内にマークビット持つ
必要はない。むしろ外にビットマップ(orバイトマップ)で
持った方がGC時にキャッシュを汚さずにすんで速い。

>>113
スペースよりむしろ速度に効果大。メモリアクセス回数が
激減するので。

119 :デフォルトの名無しさん:01/10/14 05:56
>>117
mark-and-sweepだと移動が無いから速いでしょう。
でもフラグメントが・・
これを踏まえると、
余裕があったら配列関係(文字列、シンボル、...)の時はstop and copy
consやらその他の時はmark-and-sweep
でしょうか。

120 :デフォルトの名無しさん:01/10/14 06:04
>>118
>外にビットマップ(orバイトマップ)
これは良い考えですね。
いままで思い付かんでした。

121 :96:01/10/14 06:15
GCについて。
http://www.hitachi-sk.co.jp/Products/SuperJ/gabeji.htm

122 :Part2の1:01/10/14 07:06
(これからLISPやSchemeの処理系作ろうと思ってる人向け)
・gcがらみのバグ対策
基本的な事かもしれないですが、良く引っかったバグなので。
CなどのLISP実装言語側でcons演算+セル生成を何も考えずに行なおうとすると、
その処理が終了するまでに空きセルが尽きてしまい、gcが発動してしまう
恐れがあります。その事態が起きると、操作中のconsの値が変化している、
もしくは無効になっている可能性があるので、あらかじめ処理中に生成する
consの数を数えておいて、空きセルがそれよりも少なかったら処理を行なう
前にgcを強制起動させた方がいいです。この方法は必要セルを数える事で、
2重管理になってしまい面倒ですが、プログラムが複雑になる事がありません。
または、ポインタのポインタを使い、演算を行なうconsを参照している
ポインタを全てフックしておいて、gc時に一緒に値を書き換えます。
余計なロジックが入りますが、一度に生成するconsがそんなに無いならば
こちらが楽かもしれません。
また当然ですが、gc起動後にセルが必要量存在していなければこの対策を
行なっても意味が無いので、満たなかったら新たにメモリを割り当てます。
・・というわけで演算中のgc起動は、不具合の元になるのでご注意を。

123 :COBOLER:01/10/14 08:00
書きかけの仕様書ハケ−ン
http://mentai.2ch.net/test/read.cgi/prog/963134110/l50

124 :デフォルトの名無しさん:01/10/14 11:40
>>109
> consセルで16バイト(car/cdr/type/virtual) しかもその都度newしてたんで。

newって、defaultのやつ?
自作cons poolから取ってくるようにoverrideしたやつ?

defaultのやつなら、memory管理用のtagが付いて更に4〜8byte費やしているよね。

125 :デフォルトの名無しさん:01/10/14 13:16
>>122
conservative GC だとそれは必要ないんじゃないの?

ポインタを全部フックしておくやり方は一部の実装では使われているが、
そういうのは大抵遅いし、全体としては少数派なような。

126 :デフォルトの名無しさん:01/10/14 13:29
>>122
この問題は致命的な割に処置が甘くなりがちな気がする。
というか、全く処置を行なってない処理系がありそう。
実行速度に気を取られ、開発初期段階からメモリブロックを
大きく確保しすぎて、偶に起動されるgcによる破壊に気付かず、
「原因不明のバグ」としてしまうケース。(w

127 :デフォルトの名無しさん:01/10/14 13:49
>>125
自作gcにありがち。

128 :デフォルトの名無しさん:01/10/14 15:45
>>125
同意。いかにもシロートなやり方。
処理の途中でGCが起きるなんて当たり前でしょーが。

129 : :01/10/14 16:43
Schemeのdefine-syntaxとかsyntax-caseとか、
SCMでもDrSchemeでも "unbound variable" なんですけど…。
どの処理系なら実装してるんでしょう?

解説ページもあんまりないし、一般的じゃないのかなぁ。

130 :デフォルトの名無しさん:01/10/14 17:33
でもconservativeGCって気持ち悪いんですけど。

131 :デフォルトの名無しさん:01/10/14 17:45
継続について詳しくかかれている資料ありませんか?
R5RSだとあまり良く分からなかったので

132 :デフォルトの名無しさん:01/10/14 17:54
>>58
(defun remove-success (clause)
(cond
((atom clause) clause)
(t (remove nil (remove '$success$ clause :test #'deep-member)))
)
)
ここってremoveがカラになるの?
???

133 :デフォルトの名無しさん:01/10/14 18:12
>>131
プログラミング言語scheme ピアソン・エデュケーション
ケント・ディヴィグ著 村上雅章訳

134 :131:01/10/14 18:13
↓コレがokで、
(define cc '())
(call-with-current-continuation
(lambda (x)
(begin
(set! cc x)
(display "test1")
(display "test2"))))
(cc #t)

↓コレがだめな理由がわかりません。
(define cc '())
(begin
(call-with-current-continuation (lambda (x) (set! cc x)))
(display "test1")
(display "test2"))
(cc #t)

大域では継続を束縛できないのですか?

135 :デフォルトの名無しさん:01/10/14 18:45
>>134
その処理系は、
トップレベルでは環境だけ保存してるって事かな?
beginをletに変えてローカルフレーム作ってやればうまくいくかも。

136 :デフォルトの名無しさん:01/10/14 18:46
>>128
conservativeじゃないgcの場合はどうするの?

137 :131:01/10/14 18:54
>>135
あ、ごめんなさい。
okとダメなの、逆でした

138 :BASICER:01/10/14 19:00
>>132
なんかリアルタイムマルチタスクの処理の一つが放置されているのだ

139 :デフォルトの名無しさん:01/10/14 19:12
>>136
Cで書くというやり方に固執する場合、
C処理系になるべく依存しないようにするには、
GC対象のオブジェクトはすべて、
ソフトウエアスタックや特定の大域変数から
たどれる場所に置いとく必要がある。

CのスタックやCPUレジスタをGCが直接見て、
しかもconservativeでないやり方も
当然ありうる。GCが見るルートはあらかじめ
決めておく。オブジェクトが動くかも知れない
ことを、プログラマがちゃんと意識して書く。

Lispコンパイラを使ってライブラリを
Lisp自身で書くなら、特段の配慮は必要ない。
スタックフレームのレイアウトやレジスタの使い方は
コンパイラが当然知っているから。

GCまでLispで書くのはかえって面倒だろうけど、
Lisp関数ライブラリやインタプリタは
Lispで書くのが当然いちばん楽。

140 :デフォルトの名無しさん:01/10/14 19:14
>>129
結局見つからないって事は、
defmacroの方がつぶしが効くからだな。

141 :131:01/10/14 19:33
継続のこの動作がやっぱり理解できません
(define cc1 '())   => #<done>
(define cc2 '())   => #<done>
(call-with-current-continuation (lambda (x) (set! cc1 x)))
(begin
 (call-with-current-continuation (lambda (x) (set! cc2 x)))
 (cc1 #t)
 (display "test1")) => #t*1
(display "test2")  => test2#<done>
(cc2 #t)        => #t*2
(display "test3")  => test3#<done>

*1 どうしてココでの評価値が #tなのか
*2 どうしてココで無限ループに陥らないのか。

142 :デフォルトの名無しさん:01/10/14 19:48
(cc1 #t)
したときにcc1に束縛されている継続は、
引数をただ返すだけの継続だよ。

(call-with-current-continuation (lambda (x) (set! cc1 x0)))
が(begin)の中に入ってる絵を想像してるんじゃないの?

143 :142:01/10/14 19:50
前者を補足すると、「引数を返してインタラクティブ環境に戻る」ね。

144 :デフォルトの名無しさん:01/10/14 19:52
>>141
トップレベルの式の継続は、
(define print-read-eval
 (lambda (x) (display x) (newline)
  (print-read-eval (eval (read) (interactive-environment))))
みたいなものだと思えば良い。
cc1にはset!でprint-read-evalが入ると思えば良い。

(cc2 #t)すると、(cc1 #t)が実行されるから、
#tを表示した後、新たにreadが始まる。
さっきreadしたものは関係ない。
(read)は呼び出すたびに違う値を返す関数だから。

145 :デフォルトの名無しさん:01/10/14 20:12
DrSchemeはわかりやすくていいんだが、Windows98だと1000回くらい繰り返す再起処理をステップ実行させたときにリソース食いすぎてOSごとおちることがある。
だもんで、ドスパラでWindows2000のマシンを注文した。ついでに17インチ液晶モニターも。15マソの出費だ。
こう書くとかならず「Linux使えやゴルア」というカキコがあるが、LinuxなんてCとGuileとviとEmacs Lispが使いこなせないとまともに使えない。
わかんないことがあるとすぐ「ソース読めゴルア」の世界だし。
漏れはSchemeの勉強がしたいだけだしSchemeに集中したいので、余計な作業が増えるのはいやなのだ。
sage.

146 :デフォルトの名無しさん:01/10/14 20:23
>>145
お金持ちやの〜

147 :デフォルトの名無しさん:01/10/14 20:30
Winなんて『何が使いこなせても』まともに使えない。
セキュリティパッチが出てないか頻繁にチェックしないといけないし。
ネットワークの設定変えただけでリブートしないといけないし。
わかんないことがあるとすぐ「インストールし直せゴルア」の世界だし。
漏れはSchemeの勉強がしたいだけだしSchemeに集中したいので、余計な作業が増えるのはいやなのだ。

148 :デフォルトの名無しさん:01/10/14 20:36
>>145
>>147 みたいな不毛な論争が始まるから、あんま挑発的なこと書くなよ…ハァ

149 :131:01/10/14 21:16
まずは、返信ありがとうございました。

> (begin)の中に入ってる絵を想像してるんじゃないの?
引数を返す継続と言うのが分かりません。
(begin)の中と外では動作が違うということですか?
もし、違うとしたら、それは必然的にそうなるものなのか、
例外としてそうするのか、教えてください。

> さっきreadしたものは関係ない。
継続は、評価すると束縛しなおさない限り、
普通の実行コンテキストと同じように変化しつづけるものということですか?
#他言語のgoto先のラベルみたいに。

150 :131:01/10/14 21:17
s/#他言語のgoto先のラベルみたいに。 /他言語のgoto先のラベルみたいに、一定位置にとどまりつづけるものではなく。/

151 :デフォルトの名無しさん:01/10/14 21:31
DrSchemeの話ばかりでてるが、
MIT Schemeはどうなん?

152 :デフォルトの名無しさん:01/10/14 21:49
>>145
Petite Chez Scheme と ChezEditはいかがですか。
http://www32.tok2.com/home/nak/eucs/scheme/
に紹介があります。Win2000でもOKです。軽快ですよ。「プログラミング言語scheme」 ピアソン・エデュケーション
 のケント教授が主要開発メンバーです。

153 :142:01/10/14 21:52
つまりね、

A:
(call-with-current-continuation (lambda (x) (set! cc1 x)))



B:
(begin
 (call-with-current-continuation (lambda (x) (set! cc2 x)))
 (cc1 #t)
 (display "test1"))

との間に連続性はないわけよ、インタラクティブ環境だと。
インタラクティブ環境でなく、逐次実行しているコンテキスト、たとえば

(begin
 (call-with-current-continuation (lambda (x) (set! cc1 x)))
 (call-with-current-continuation (lambda (x) (set! cc2 x)))
 (cc1 #t)
 (display "test1"))

とか

(begin
 (call-with-current-continuation (lambda (x) (set! cc1 x)))
 (begin
  (call-with-current-continuation (lambda (x) (set! cc2 x)))
  (cc1 #t)
  (display "test1")))

だと連続性があるから、ループになるわけ。

154 :136:01/10/14 21:53
>>139
説明がいまいち掴めないんですが、
結局 >>122 の後者の方法を行なうって事でいいんですか?

>CのスタックやCPUレジスタをGCが直接見て、〜
のあたりも良くわかりませんでした。
簡単にCのスタックを辿ることが可能なんでしょうか?

で、最後のLISPonLISPの話はわかりました。

155 :131:01/10/14 22:02
>>153
ごめんなさい、そしてありがとう。
疑問が一気に氷解しました。

トップレベルとはその名のとおり、トップレベルで、
さらに上にrootがあるわけではないってことですね。
それぞれの手続きがルートと言うことで。

156 :デフォルトの名無しさん:01/10/14 23:31
VSCM http://www.cs.princeton.edu/~blume/vscm/ はどう?
ANSI C で書かれた仮想マシン上で動くんみたいよ。
バイトコードコンパイラはScheme自身で書かれているって。

(なんか作者はもう他の言語に興味移ってやる気ないみたいだけど)

157 :デフォルトの名無しさん:01/10/15 00:10
>>145
正直、そこまでしてSchemeに集中したいというのはスゴイと思った。
「Schemeのみ」というこだわりとカネの使い方からして老後の趣味っぽいけど。

158 :デフォルトの名無しさん:01/10/15 00:32
>>146
>>157
きみら15マン程度の現金で金持ちかよ。
それじゃACLも買えないよ。

159 :デフォルトの名無しさん:01/10/15 01:30
下位bitのpairの型情報を0にすれば-1する必要なくなって、
速いんじゃない?マスクすら必要ないし。

160 :デフォルトの名無しさん:01/10/15 01:42
>>118
その方法はメモリがリニアじゃない環境(8086/Palmなど)も
考慮すると、1オブジェクト毎にセグメント探索入るから
遅くて使えないです。オブジェクトから相対的にしか見えないんで。
何か良い方法はあるでしょうか。

161 :デフォルトの名無しさん:01/10/15 01:55
>>159
だからアクセス時には元々マスク
なんかしてないって。

pairのタグが1だとして、嘘アセンブリ言語で書くと
 load r1, [r2 - 1] ;r1<-car(r2)
 load r3, [r2 + 3] ;r1<-cdr(r2)
としてるだけ。

pairのタグをゼロにしても速くならんが、
fixnumのタグはゼロでないと遅くなる。

>>160
良くワカランが、セグメントごとにビットマップ
持つとかすれば良いんじゃね〜の?

ChezSchemeは確かページごとにビットマップ持ってる。
同じページには同じ大きさのオブジェクトだけ集めて。

162 :デフォルトの名無しさん:01/10/15 02:02
>>154
配列で作ったスタックに自分で待避しとけば
いつGCが起きても問題は起きないし、
Cレベルでは当然そう書くと言うこと。

CのスタックやCPUレジスタまで見るのは、
もちろん簡単にはできないが、
自分でLispコンパイラ書くよりは少し楽。

163 :デフォルトの名無しさん:01/10/15 02:12
>>153
>との間に連続性はないわけよ、インタラクティブ環境だと。
連続性があると考えても良い。
その場合でも無限ループにはならない。
>>144 参照。

>> さっきreadしたものは関係ない。
>継続は、評価すると束縛しなおさない限り、
>普通の実行コンテキストと同じように変化しつづけるものということですか?
>他言語のgoto先のラベルみたいに、一定位置にとどまりつづけるものではなく。

(cc2 #t)
->((lambda(dummy)(cc1 #t)(print-read-eval(display "test1"))) #t)
->ここで(cc1 #t)が評価されると、継続
 (lambda (dummy2) (print-read-eval(display "test1")))は捨てられて…
->((lambda (x) (print-read-eval x)) #t)
->(print-read-eval #t)
->#tがプリントされ、read待ちになる。

164 :デフォルトの名無しさん:01/10/15 02:52
>>163
この文脈だと
=連続性がない、だと思うんだが、どうか。
それにそれは実装依存の話ではないのか。知らないが。

165 :136:01/10/15 02:54
>>162
ありがとうございます。
ということは、Cで普通にやる場合、
やっぱり>>122の方法ってことですか。
gcが参照できる様にグローバルかスタック上の
変数や配列をフックする仕組みを作っておくと言うことで。

直接スタック覗くのは素人には難しそうです。
allocaやvarargライクな特殊処理になるかと想像・・。

166 :161-163:01/10/15 03:58
>>164
むー、そうかな。

トップレベルがSchemeで書いたread-eval-printループを実行してるとしても
同じだよ、と言う意味なんだが、そうするとどことどこが不連続になるんだろ
うか。(もちろん実際どうなってるかは処理系による。)

>>165
フックってのは、
 obj **stack[N]; /* GCのルート"を指す"間接ポインタ */
 obj **sp = stack;
 #define gc_protect(var) (stack_check(), *sp++ = &(var))
 #define gc_unprotect(n) (sp+=n)

 obj *append(obj *list1, obj *list2)
 {
  obj *tmp;
  gc_protect(list1);
  gc_protect(list2);
  ...cons(list1, list2);
  gc_unprotect(2);
 }
みたいな意味じゃないの?

漏れが言ってるのは、上よりも、
 obj *stack[N]; /* GCのルート */
 obj *append(int argc, obj *argv[])
 /* 引数はargv(スタックのどこか)に入って渡される */
 {
  ...
 }
とか、
 obj *reg0, *reg1, *reg2, ...; /* GCのルート */
 obj *stack[N]; /* これもルート */
 obj *sp = stack;
 #define push(val) (stack_check(), *sp++ = (val))
 #define pop() (*--sp)
 obj *append(void)
 /* 引数はreg0とreg1に渡される */
 {
  ... push(cons(reg0, reg1));
 }
とかの方が良いんじゃないか、ということなんだが…

167 :デフォルトの名無しさん:01/10/15 05:37
おいおい このスレ ガーベッジコレクションの入門書になるよ

168 :デフォルトの名無しさん:01/10/15 06:56
Schemeのlexical rule、マトモに実装している処理系ってあるの?
たとえば、+で始まる識別子へのバインド

(define +v 100)

vscheme : 通る
DrScheme : 通る
rhizome : 通らない

r5rsを読むと通らないのが正確みたいだけど

169 :デフォルトの名無しさん:01/10/15 11:08
すみません。
しょうもない質問なんですが、LispとSchemeやってる人は何と呼ばれるんでしょう?
Lisper, Schemerでしょうか?

170 :デフォルトの名無しさん:01/10/15 11:45
>>169
LispはLisper Schemeは>>71

171 :デフォルトの名無しさん:01/10/15 12:27
DrSchemeの日本語入門書早く出ろ。
解説サイト見ながら実行するとハードディスクがけたたましくて
かなわん

172 :デフォルトの名無しさん:01/10/15 12:30
>>171
代わりに新しいマシンを買ったら?
安いでしょ、今なんて4万ぐらいで買えるし

173 :デフォルトの名無しさん:01/10/15 15:06
それは聖地秋葉原の話っしょ

174 :デフォルトの名無しさん:01/10/15 20:58
>>173
横浜方面で良い店ない?

それはともかく、LISPやSchemeのOSがあった筈。

175 :デフォルトの名無しさん:01/10/15 21:11
fanOSだっけ?

176 :173:01/10/15 21:59
当方北海道

177 :Part2の1:01/10/15 23:29
>>166
ご明察です。
> #define gc_protect(var) (stack_check(), *sp++ = &(var))
> #define gc_unprotect(n) (sp+=n)
122はこっちの方を指しています。
自分の考えでは、Cではグローバルよりauto変数を使った方が
効率の良いコードを生成するのではないかということで、
フックを推薦します。どっちが良いかは計ってみないと何とも
言えませんが。

あと気を付けるべき点として忘れてましたが、以下の様な
コードを作成すると、
r = cons(cons(a,b),cons(c, d));
a,b,c,dをフックしていても、a,b側か、c,d側どちらかのconsで
gcが起動し、最後のconsの片側に無効な値が入力される恐れがある。
この場合は以下の様に書き換える事。
a = cons(a,b);
r = cons(a,cons(c, d));
または
c = cons(c,d);
r = cons(cons(a, b), c);
(a,b,c,dがフックされている事が前提)

178 :デフォルトの名無しさん:01/10/15 23:56
>>168
日本語も通りますがなにか?

179 :デフォルトの名無しさん:01/10/16 00:17
>>178
いや、そういうことじゃないんだが。

識別子 = <頭字> <後続文字>* | <特殊な識別子>
頭字 = 文字 | 特殊な頭字
文字 = a-z
特殊な頭字 = !$%&*/:<=>?^_~
特殊な識別子 = + | - | ...

ピリオドで始まる識別子は ... のみで、他のピリオドから始まる
トークンは認識できないはずなんだが

180 :デフォルトの名無しさん:01/10/16 00:18
ピリオド>あ、ピリオド等

181 :デフォルトの名無しさん:01/10/16 00:23
最近の漏れの遊び。

(define (A x)
(B (+ 2 x)))

(define (B y)
(A (* 3 y)))

(A 2)

こんな感じのS式をDrSchemeに入れてステップ実行させてにやにやする。

182 :デフォルトの名無しさん:01/10/16 01:28
>>177
確かにautoを使うとレジスタに割り付けてくれたりするが、
関数呼び出しの時を考えると、プログラマがスタックに参照
を積む手間に”加えて”、Cコンパイラもレジスタをスタック
に待避することを忘れてはいけない。下手をすると、待避・
復帰のコストが倍になる。

最適化Lispコンパイラで関数をどんどんインライン展開しな
い限り、Lispでは関数呼び出しのコストがほとんどと思われ。
(+とかcarもインタプリタではいちいち関数呼び出しになる
のだから。)

ところでここはage進行で良いのか?

183 :デフォルトの名無しさん:01/10/16 01:37
>>168,179

R5RS 2.1には、
 正確にどういう文字列が名前となるかは処理系によって異なる。
 しかし、どの処理系でも、数の始まりになり得ない文字で始まる
 英字・数字・拡張英字の並びは名前である。
 また特に+, -, ...は名前である。
とある。

.で始まる文字列とか+vとかは、すべての処理系で名前と見なされ
るとは限らない。しかし、処理系はこれらを名前と見なしても良い。

184 :デフォルトの名無しさん:01/10/16 01:46
>>182
>ところでここはage進行で良いのか?
質問ある人はageるんだし、どっちでもいいんじゃない?
最近はカキコも多いし。

185 :デフォルトの名無しさん:01/10/16 02:20
>>183
thx!

R5RSにバージョンなんてあったんですね。
しかし、私が参考にしている訳版はバージョン表記が無いです。
いくつなんだろ

186 :デフォルトの名無しさん:01/10/16 02:32
>>185
バージョンじゃなくて、R5RSの
2.1 Identifiersという節のことです。

187 :デフォルトの名無しさん:01/10/16 02:44
string->symbolとか標準関数にあるから、
別に+vがあってもいいと思うけど。
なんでもかんでも文字列にする
->stringとか書きたいし(w

188 :デフォルトの名無しさん:01/10/16 03:33
そういうことですか。ありがとうございました。
最低限識別子となりえるものだけ定義しているんですね。

そうなると、できる限り多くを識別子と扱えるようにする方が良いですね。

189 :デフォルトの名無しさん:01/10/16 03:34
昔のScheme(R3RSのころ?)だと、1+と-1+という
標準関数があったと思う。

190 :デフォルトの名無しさん:01/10/16 11:05
>>182
autoでも、&でアドレスを要求しちゃうとレジスタには割り付けられないと思われ。
なので「フック」(っていうのか?)に利点は無さそう。
自分で退避した方が速いと思われ。

191 :Part2の1:01/10/16 12:31
Σ(゚д゚lll)ガーン

192 :デフォルトの名無しさん:01/10/16 19:41
>>181
(。U。); カコイイ

193 :BASICER:01/10/16 19:56
>>145
ブラウザ立ち上げながらやってんなら
ブラウザは、先に立ち上げてDrshemeは一番最後に立ち上げて見て。
一応裏技

194 :デフォルトの名無しさん:01/10/16 21:57
call/ccを使った無限ループ
(define loop (lambda (cont) (call/cc loop)))
(loop '())

195 :デフォルトの名無しさん:01/10/17 00:18
>>103

えーと、ようするに
10をtempに入れる、という処理は、
obj *temp;
temp = (obj*)10<<2
とする、という理解でいいんでしょうか?
それと、これをやってしまうと、4バイト境界じゃなかったら
ポインタじゃない、という判定が使えなくなるので、
さらに保守的なGC、という感じになってしまう気がするのですが。

196 :デフォルトの名無しさん:01/10/17 00:34
>>195

char* heap[SIZE_HEAP];
char* currentp = heap + SIZE_HEAP;

enum tag_t {
TAG_INT, ...
};

#define ALLOC_CELL(x) (currentp -= (x << TAGBITS))
#define BIND_TAG(p, id) (p |= TAG_INT & TAGMASK)

obj* make_int(int x)
{
int* p = ALLOC_CELL(1);
BIND_TAG(p, TAG_INT);
*p = x;
return (obj*)p;
}

こういうことじゃない?

197 :デフォルトの名無しさん:01/10/17 00:35
× char* heap[SIZE_HEAP];
○ char heap[SIZE_HEAP];

198 :デフォルトの名無しさん:01/10/17 01:07
>>195 その通り。
exactなGCで無いと使えない技術と思ってよし。

>>196 pairやsymbolと違ってfixnumは即値で表すのだ。
だからfixnum演算ではメモリアクセスが全く起きない。
ゴミも出ない。

199 :195:01/10/17 01:17
>>198

うわっ、やっちまった。
保守的マーク&スイープでこの仕組み実装しチャタヨ

うーむ、いまさら直す気もおこらないし、
超保守的GCって事でいいやヽ(´ー`)ノ

200 :デフォルトの名無しさん:01/10/17 01:56
>>194
((call/cc call/cc) (call/cc call/cc))

201 :デフォルトの名無しさん:01/10/17 18:27
ベクトルの大きさを変更する方法って無いですか?

202 :デフォルトの名無しさん:01/10/17 19:50
>>194
神の思考!→^^;→?→????????????????????

(来週までに解決しておこう!(一応冷静(本当か?(???????))))

203 :デフォルトの名無しさん:01/10/17 20:05
= (obj*)(num<<2)
ってやっちゃうと、
例えばDWORDを使うWindowsのAPIとか、外部のインターフェースを
直接扱えなくなるんじゃない?
bignum使えって?

204 :デフォルトの名無しさん:01/10/17 20:30
>例えばDWORDを使うWindowsのAPIとか、外部のインターフェースを
>直接扱えなくなるんじゃない?

当然使えないだろう。
カリカリにWindowsAPI回りをチューンしたい、
というなら違う事考えないとまずいだろうな。
でも日常的な利用なら、使う所で
(obj*)temp>>2
すれば特に問題無いと思う。
少なくとも
temp->val.ival
とかやるよかずっと早い気が。
結局ループの時のカウンタ等にポインタ辿るのが
嫌だ、という事では?

205 :204:01/10/17 20:35
(int) temp>>2
の間違いだ。スマソ

206 :デフォルトの名無しさん:01/10/17 20:37
>>204
じゃあヤパーリ各セル毎に属性1〜2バイト取った方が結局現実的なのかな?
numberにしても、'(1 2 3)というlistなら、属性に'carはnumber'
というflagを各セルに入れておけば、numberのobjectを作らずに
carに直接入れるとかできるし。
数ビットだけでやりくりするのは大変だと思った。
迷うね〜

207 :デフォルトの名無しさん:01/10/17 22:07
>>206
consの属性をpairか!pairにして、
!pairなら任意の大きさのobjectに振り分ければ?
生成されるオブジェクトの比で考えたら、
consがトップになるんではないかと。

208 :デフォルトの名無しさん:01/10/18 00:16
ある記号処理を行なうプログラムに使われるオブジェクトの集計を取ると、
((cons . 6015)
(symbol . 539)
(string . 16)
(number . 88)
(vector . 0)
(char . 0)
(true . 60)
(false . 46)
(null . 2452))
となり、consがダントツ。consとnumberは68.4倍の差。

209 :デフォルトの名無しさん:01/10/18 00:26
>>201
無い。

210 :デフォルトの名無しさん:01/10/18 00:42
>>209
Schemeには無いね。
Common Lispのadjustable-arrayなら大きさを変えられる。
またはfill-pointerつきのvectorとか。

211 :デフォルトの名無しさん:01/10/18 01:02
>>206
なんで「ヤハ゜ーリ」なの?
204は「下2ビットはタグ」が良いといってると思われ。
ちなみに漏れもそう思う。

>属性に'carはnumber'
>というflagを各セルに入れておけば、numberのobjectを作らずに
>carに直接入れるとかできるし。
良くわからんが…
セルに入れないときはどうするの?ベクタの要素が整数の時とか…
(ポインタ1個を1ワード+フラグ1バイトで表すということ?)

どうしても整数は32ビットfullに使いたい?

212 :デフォルトの名無しさん:01/10/18 01:19
>>211
>どうしても整数は32ビットfullに使いたい?
Windowsやなんかの環境でそれなりに使い物になる処理系を
考えれば32bitあった方が良いだろ。

213 :デフォルトの名無しさん:01/10/18 01:37
>>212
値が30ビットで表せない場合(けっこう稀だと思う)だけ
別の表現(bignumとか、ヒープに割り当てた32ビット値への
ポインタとか)にすれば、ほとんどの場合は速い表現が使え
るよ。

Win API呼び出す前にはどうせ型チェックするんだし。

214 :デフォルトの名無しさん:01/10/18 01:50
>>213
希な訳が無いだろー(w
Windowsとの直行性を考慮するなら最低でも32bitは必要。
個人では膨大なAPIをラップするだけのライブラリなんて作って
られないから、恐らく直接DLLを叩きたくなるだろう。
Windowsで使われる定数には0x80000000辺りを使う事が沢山ある。
ポインタ値としても。
これらをいちいち場合分けして変換する?
型チェックについてはLISPコード側でいくらでも対応できる。

215 :デフォルトの名無しさん:01/10/18 01:52
>>211
なんで2bitがいいの?
RISCプロセッサ使用者数なんてたかが知れてるんだし、
x86系にあわせてもっとフラグビット広く取った方が良くないか?

216 :デフォルトの名無しさん:01/10/18 02:05
まあこういう議論はほんとはどうでもいいんだけど、実際使う環境下で
妙な制限のある処理系って嫌でしょ?メンテナンスも大変そうだし。
作る事が目的ならそれでいい。

217 :デフォルトの名無しさん:01/10/18 02:09
>>207

どういう意味?
sizeof(int)もsizeof(void *)も俺の環境では一緒なんだが。
そういう事では無い?

>>214

そうか?
稀、というのはようするにfor文の比較のように短時間に
すごく何度も使われない、という事かと。

API呼びだしには全てまともなint使えばいいじゃん。
union misc_obj{
int ival;
};
union obj{
union misc_obj misc;
:
};

って感じのival使えば。

>x86系にあわせてもっとフラグビット広く取った方が良くないか?

俺は211じゃないが、x86ってどの程度取れるの?
てっきり4バイトアラインメントだと思ってたのだが。

218 :デフォルトの名無しさん:01/10/18 02:20
>>217
いや、4バイトにこだわらなくても良いでしょ。
3bitで8バイト、4bitで16バイトなら許容範囲じゃないの?
いまどきメモリ1G搭載してるPCなんてざらにあるんだし

219 :デフォルトの名無しさん:01/10/18 02:20
この辺の話は価値観、というか使い道によると思われ。
さらに、設計と実装に割ける時間。

220 :デフォルトの名無しさん:01/10/18 02:24
>218
>いまどきメモリ1G搭載してるPCなんてざらにあるんだし
こういう意見は聞きたくないなあ

221 :デフォルトの名無しさん:01/10/18 02:34
もちろんfixnumのタグ2ビットに限る必要はない。
また最小のオブジェクトが8バイトアラインでも
3ビットに限る必要はない。

例えば、

下2ビットが00ならfixnum
else 下3ビットが001ならpair
...
else 下4ビットが0001なら(もっとサイズがでかい型)

などというencodingも可能ではある。
つまり「下4ビットxx00はfixnum(xはdon't care)」とか。

これならメモリは特にムダにならない。

222 :デフォルトの名無しさん:01/10/18 02:42
>>217
同意。
整数の表現を1つに決める必要はない。
Scheme側で30bit表現とより長い表現があるにしても、
APIを呼び出すときに一律32bitに直しちゃえば良い話。

専用ラッパー作らないなら、
(call-dll "WinHogeHoge" #xf0087c47 x y)
とかやるのか? だったらcall-dllで「整数が来たら32bit」
にしちゃえば良い。(16bitとの使い分けはどうするんだろ?)

それともインタプリタのCコードから
WinHogeHoge(lisp_ptr, lisp_int, ...);
とかやりたい?
だったら
WinHogeHoge(lisp_ptr, TO_DWORD(lisp_int), ...);
とかしてやれば良い話と思われ。

223 :デフォルトの名無しさん:01/10/18 02:51
>222
>APIを呼び出すときに一律32bitに直しちゃえば良い話。
しちゃえば良い話なのか・・?

224 :デフォルトの名無しさん:01/10/18 03:08
>>220
いまは、多少メモリを無駄遣いしても、
早いほうがいいっていう意図で書いたんだが。
べつに、1Gフルに使い切れって言うわけじゃない

225 :デフォルトの名無しさん:01/10/18 08:54
メモリを無駄遣いしてもいいってのなら、
consを何がなんでも8バイトにする必要もないな

226 :デフォルトの名無しさん:01/10/18 09:28
>>223
>> APIを呼び出すときに一律32bitに直しちゃえば良い話。
>しちゃえば良い話なのか・・?
その後ろも読めよ(W
理解できなかったか?

>>225
>メモリを無駄遣いしてもいいってのなら、
>consを何がなんでも8バイトにする必要もないな
でかくするとメモリ転送量が増えて遅くなるってば。
局所性も悪化するし。
なんででかくしたいの?

227 :デフォルトの名無しさん:01/10/18 09:54
ここで話されているハイレベルな方々は.NETのCLRへのコンパイラを
作る予定はありませんか?

228 :デフォルトの名無しさん:01/10/18 09:55
>しちゃえば良い話なのか・・?

律儀に変換をやってくれる門番が適切な場所に居れば
いい(=速度とか以外の問題は無くなる)のでは?

「適切な場所」がどこか?は、静的に割り出し可能だよね?
それこそDLL呼び出す所とか。

229 :デフォルトの名無しさん:01/10/19 03:20
>>227
CLRのバイトコードってどんなの?
tail recursiveな関数呼び出しって可能?

Javaのバイトコードだと無理だよね。

230 :デフォルトの名無しさん:01/10/19 03:29
>>227
それは、Haskell, C--をやっていたハイレベルな人達がやっています。
Simon Peyton Jones!

231 : :01/10/19 11:46
HotDogは、なんかまだbugyyっつってたよ。

232 : :01/10/19 11:46
bugyy → buggy

233 :デフォルトの名無しさん:01/10/19 11:53
エロホン?

234 :デフォルトの名無しさん:01/10/19 23:45
(エロホンp HotDog)
=>nil

235 :デフォルトの名無しさん:01/10/20 00:39
JITコンパイラのScheme処理系ってありますか?

236 :デフォルトの名無しさん:01/10/20 18:12
kawaは?

237 :デフォルトの名無しさん:01/10/20 18:22
なるほどkawaか…
うーんと、自分で直接ネイティブコードを吐くやつ、とい
う意味だったんですが…

238 :デフォルトの名無しさん:01/10/20 18:47
>>237

コンパイラじゃ駄目なの?

239 :デフォルトの名無しさん:01/10/20 20:00
>237
「scheme native code」検索で見つかった。
pscheme
http://www.angrygraycat.com/scheme/pscheme.htm
あとPalmで動くLispMeってそういう処理系じゃなかった?

240 :デフォルトの名無しさん:01/10/20 20:10
あとGambit Scheme
http://www.iro.umontreal.ca/~gambit/

241 :デフォルトの名無しさん:01/10/20 20:16
lisp系ってコンパイラさえあれば、
簡単に実行時でもいつでもコンパイルできると思うが。
S式を動的生成して、普通にevalする代りにcompile-evalする。
でもこのケースはバイトコードコンパイルする処理系に限られるかも。

242 :デフォルトの名無しさん:01/10/20 21:29
schemeといえばやっぱりchez。
http://www.scheme.com/

243 :デフォルトの名無しさん:01/10/20 21:30
いくらよ?>242

244 :デフォルトの名無しさん:01/10/20 21:38
SchemeでGUIとかやると
call-with系とlambda駆使で一本の関数にできるのがいい。
(name-spaceを汚さない)
その代わりすげーネストになるけど。

245 :デフォルトの名無しさん:01/10/21 00:29
pschemeは「将来native code compilerも作る」と書いてあるように見えるん
ですが…
Gambitって68k版以外はCへコンパイルするんですよね。JIT…なのかな?

「S式を入れたら即nativeにコンパイルされて実行」っていうのがあるのかな、
と。あるならどのくらい速いのかと思って。

246 :デフォルトの名無しさん:01/10/21 01:03
>>245
ゴミをどう扱うかによるかな。

247 :デフォルトの名無しさん:01/10/21 01:06
コンパイルしてgcを完全に取っ払う事って可能?

248 :デフォルトの名無しさん:01/10/21 01:14
制限付きで可能。>247
全部は無理。

249 :デフォルトの名無しさん:01/10/21 01:17
>>247
漏れは246ではないが
コンパイルしたコードがゴミになったらどうするか、
ということかと思われ

トップレベルから入れた式は、define以外すぐゴミに
なるよね。

250 :デフォルトの名無しさん:01/10/21 01:29
コピーGCだと、コンパイルコードもコピーされて動くんですか?

251 :デフォルトの名無しさん:01/10/21 01:33
>>250
そういう処理系もある(JITは知らんが)。
VAX NILのコンパイラは確か、「どの2命令の間でも、コー
ドやスタックがコピーされて動いている可能性がある」と
想定したコードを吐いていた。

252 :デフォルトの名無しさん:01/10/21 05:32
色々遊びたいならbytecode化がお勧め。
S式をlambda-closureの連鎖に変換する例はSICPに載ってる。
(SICPの例ではlambda-closure自体もS式なので速度はあまり改善されないけど。)

253 :デフォルトの名無しさん:01/10/21 15:54
VAXなんて知ってる奴いるのか

254 :デフォルトの名無しさん:01/10/21 16:28
VAX-11 = Virtual Address eXtension of PDP-11
NIL = New Implementation of Lisp

255 :デフォルトの名無しさん:01/10/21 16:41
ローレベルな部分の実装について書いてる人が多いけど、
個人的には趣味でschemeのインタプリタを実装する時に、
マクロの実装が一番大変だと思うのですが?

256 :デフォルトの名無しさん:01/10/21 16:47
>>255

俺は継続だと思うが。というか今継続で苦戦している。
マクロってevalみたいなの実装するのと大差無い気が。
まだ実装してないが。

257 :デフォルトの名無しさん:01/10/21 19:11
おれもマクロの実装はたいしたこと無いと思う。
マクロ定義自体はSchemeで書けばいいんだし。

proper tail recursionがちゃんとできれば、
継続も自然とできると思うがなー

258 :255:01/10/21 23:03
継続も大変だと思う。proper tail recursionは根性でできるけど。
個人的には継続は2種類くらいしか実装方がないような気がする。
スタックをコピーして継続使わなければ早いけど継続は遅いっていうのと、
プログラムをCPSとかバイトコードに変換してから実行するっていうやつ。
がんばれば出来そうだ。

僕の頭ではマクロのアルゴリズムが理解できない。
というか、実装方法がよく分からない。
R5RSのsyntax-rulesの定義以外の解説が欲しい。

259 :デフォルトの名無しさん:01/10/22 02:17
つーか…
call/ccでオブジェクトレベルにリフレクトされた継続は
ヒープに置いとくわけだが、
 1.最初から全部ヒープに置いとく
  (スタックフレームをリスト構造で表現)
 2.全部スタックに置いといて、必要なときに全部ヒープにコピー
の他、
 3.小さいサイズのスタックを使い、あふれたらヒープにコピー
とかの変種もあるよ。

「究極にチューンすれば、1でも3でも効率はほぼ同じ」
という研究があったような。

260 :デフォルトの名無しさん:01/10/22 11:01
>255
マクロはevalでマクロ呼び出し自体のコードに対してquoteしたものを
渡すだけでいい。マクロ定義自体は入出力がリストのただの関数。
macroさえ実装すれば、
define-macro -> define/let/letrec-syntax(syntax-rule/case)
とSchemeコード側で拡張できる。

同じマクロを毎回実行時に展開するのは無駄。
マクロキャッシュを実装もしないと遅い。これは組み込んだ方が良い。

261 :デフォルトの名無しさん:01/10/23 00:33
>>260
キャッシュはいつflushしたら良いでしょう?
1.トップレベルに戻ったとき
2.1つでもmacroが定義されたとき
3.キャッシュされているmacroが再定義されたとき、関係あるものだけflush

262 :デフォルトの名無しさん:01/10/23 00:56
R5RSのマクロって仕様書厳密に読むと
「前もって展開はできない」って解釈できない?
なんかそんな気がしたんだけど、勘違いかなあ。

263 :デフォルトの名無しさん:01/10/23 01:45
>>262
マクロキーワードが変数として束縛されたら
マクロじゃなくて変数として扱わなきゃならないけど・・・

変数のスコープが静的だと考えれば、前もって展開しちゃっても
いいんじゃない?

264 :無名λ式:01/10/23 02:00
http://www.psg.com/~dlamkins/sl/chapter20.html

265 :260:01/10/23 15:08
>261
マクロを評価(展開)するときにキャッシュにあればそれを優先させるだけ。
トップレベルのマクロに対してはキャッシュは(多分)意味が無い。
フラッシュする必要はない。必要なくなれば適当なタイミングで削除する。
起動毎に展開結果が変化するマクロについてはキャッシュを適用できない。

266 :デフォルトの名無しさん:01/10/23 17:42
>>265
formを引数としてmacroexpandが呼ばれたときに、
キャッシュを検索する、という感じでしょうか?

form自体のcarとcdrを展開結果のcarとcdrで置き換えちゃう
ことを考えていました。

267 :260:01/10/23 20:28
>>266
直接書き換える処理はよほどうまくやらないと危険。(昔試した。)
+オリジナルコードを後で参照できなくなる。
さらに、ほとんどの場合、展開後のコードは読めない(読みたくない)。
キャッシュが実装できない時は、macro-expandを用意して
明示的に展開してしまう方法が簡単。

268 :デフォルトの名無しさん:01/10/24 23:18
よさげなページ見つけた。
慶応の授業のページ。
記号処理プログラミング 2001
http://buri.sfc.keio.ac.jp/lisp/menu.html

269 :デフォルトの名無しさん:01/10/25 01:19
(define (A x y)
(cond ((= y 0) 0)
((= x 0) (* 2 y))
((= y 1) 2)
(else (A (- x 1)
(A x (- y 1))))))

↑これってアッカーマン関数ってゆーんですね。今はじめて知りました。ところで、これで
(A 3 13)
を DrScheme で計算させたらメモリーが足りなくなって処理系ごと落ちました。
OSは無事でしたが。

270 :デフォルトの名無しさん:01/10/25 01:32
>>269
ちょっと違うぞ(w
(define ack
_ (lambda (x y)
_ (cond ((= x 0) (+ y 1))
_ ((= y 0) (ack (- x 1) 1))
_ (else (ack (- x 1) (ack x (- y 1)))))))
が正しい。

(ack 3 13)は今の計算機でもちょっと厳しいかも。
(ack 3 9)くらいにしとけば。

271 :デフォルトの名無しさん:01/10/25 01:42
>>270
あー正式な定義はそうなんですね。
私のは
http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-11.html#%_sec_1.2.1
こっからうつしただけなので。

それで、今のコンピューターでも (ack 3 13)は計算できないんですかねぇ?
セレロン1GHz メモリ512MB なんですけど、、、

コンピューターでできないてことは当然紙と鉛筆でもできないだろうし。

こまりましたねぇ、素人相手に
「はっ、そんなケーサンコンピューターにやらせればいーだろうが、けっ!」
てな感じでいばれないじゃないですか。

272 :デフォルトの名無しさん:01/10/25 13:02
ここのスレの人々はなんでこんなにくわしいんだろう。
見てて鬱になるよ。仕事でScheme実装でも作ってんのかな。
それともソレ系の研究者がたまたま集結してんのかな。
そんな人は日本に何十人もいないと思うんだが…。

273 :デフォルトの名無しさん:01/10/25 15:43
>>271
竹内関数もよろしく
(defun tak (x y z)
_ (if (> x y)
_ (tak (tak (- x 1) y z) (tak (- y 1) z x) (tak (- z 1) x y)
_ y))

274 :デフォルトの名無しさん:01/10/25 21:56
>>273
竹内関数てのもあるんですね。
しかし、アッカーマンといい、いったい、どれだけのメモリーがあれば計算できるんでしょうか、、、

275 :デフォルトの名無しさん:01/10/25 22:31
>>272
住民に蛇胃酢戸多し。

276 :デフォルトの名無しさん:01/10/25 23:00
ジャイスト??

277 :デフォルトの名無しさん:01/10/25 23:15
>>275
漏れは名椅子戸。
嘘、実は本号。
嘘、実はDQN(藁

278 : :01/10/25 23:17
ヘビイストって呼んでしまった

279 :デフォルトの名無しさん:01/10/25 23:43
メイイスト?
ナイスト?
本郷=灯台?

280 :デフォルトの名無しさん:01/10/25 23:52
2ch直りん隠しページのアクセスログの集計だと、
じ:100
な:20
本:3
ぐらいだった。
ぶぶづけ、goもいる。

281 :デフォルトの名無しさん:01/10/26 00:21
じってなんだぁ〜
なってなんだぁ〜(泣

282 :273:01/10/26 00:28
>>274
諦めてください(w
アッカーマン関数とか竹内関数は,停止はするけど
ループだけでなく再帰を使わないと定義できない関数
(原始帰納的でない一般帰納的関数)の有名な例であり,
引数が大きくなるにつれて,消費する計算リソースは
ループだけで定義できるような関数(原始帰納的関数)とは
比べ物にならないぐらい大きくなります.

283 :無名λ式:01/10/26 00:38
あ、マクロのClingerさんのpage発見。
"Hygienic macros through explicit renaming"
"Macros in Scheme"
"Macros that work"
辺りをどうぞ。> macro-expansionな日々の方々

284 :デフォルトの名無しさん:01/10/26 00:46
ナルシスト

ナルといえば、ロブスター味噌煮込み定食の味はいかなるものか、
解説してください>本号の人

285 :無名λ式:01/10/26 01:05
>>283
あ、URL忘れてる…
http://www.ccs.neu.edu/home/will/papers.html
井田さんがどれかをbitに紹介していたような気がする。

286 :デフォルトの名無しさん:01/10/26 01:14
じ:JAIST
な:NAIST

287 :名無しさん@Emacs:01/10/26 20:51
scheme の関数よび出しは list の symbol を評価してその値を関数として
使うと聞いてるのですが, それは lisp で書くとこんな感じになりますか?

(defun test (&rest rest)
(eval (cons test rest)))
;; 実験
(setq test '(lambda (a b) (* a b)))
(test 2 3) => 6
(setq test '(lambda (a b c) (+ a b c)))
(test 3 3 2) => 8

symbol の function cell をこんな風にしておくと, value cell を
関数として使えると思うのですが.
scheme はよく知らないので, 感違いしていたらすみません.

288 :デフォルトの名無しさん:01/10/26 20:57
>>287
ちょっと言葉使いがアレですが、SchemeではLispと違い
symbol-functionスロットがなくて、関数呼び出しの式の最初の式も、
他と同じようにevaるのは本当です。

良い点と悪い点があります。Schemeの方がきれいですが、遅くなります。
Lispだと、functionスロットには関数しか入らないように保証できるので、
呼び出す前にチェックする必要がありません。

83 KB
■ このスレッドは過去ログ倉庫に格納されています

★スマホ版★ 掲示板に戻る 全部 前100 次100 最新50

read.cgi ver 05.04.00 2017/10/04 Walang Kapalit ★
FOX ★ DSO(Dynamic Shared Object)