1 :
デフォルトの名無しさん :
01/10/09 08:39
マ板の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
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です。
なんか表紙が赤い本です。
>>7 GCのたびにハッシュ表をスキャンして、GCで
コピーされたハッシュキーだけハッシュしな
おすのが定石なり。
キーが長寿命領域に逝ってしまえばrehash回
数は激減するのでだいじょうぶ。
#しかし厨房が増えたな…fexprなんてコン
#パイラを使わない時代の化石だろー
>>13 > #しかし厨房が増えたな…fexprなんてコン
> #パイラを使わない時代の化石だろー
ん? lambdaに&rest、&optionalがない、macroがない時代の化石、でしょ?
それに、FEXPRを使っている本のprogramを動かしてみたいようだから仕方がないよ。
# Winstonの"LISP"という手もあるが…
>>14 そういやlexprなんてのもあったね。&restが
あれば不要だが。
fexpr使っちゃうとコンパイル不可なのが欝。
17 :
デフォルトの名無しさん :01/10/12 06:56
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 -- 動かし方はこんな感じです。
>>16 lexprって、引数が普通に評価して渡される、
可変個引数の関数のこと。MacLisp。
(DL LIST (X) X)
みたいな感じ。(Xのまわりのカッコは確か
要ったと思う。)
exprも引数を評価してから関数に渡されるけど 引数の数は固定って事はlexprはexprよりも高機能って事ですね?
21 :
デフォルトの名無しさん :01/10/12 12:53
ただ、
>>15 が言うように、
コンパイルしても、引数へのアクセスがスタックポインタ+オフセットにならないわな。
引数列をリストで渡して貰うわけだから。セルも消費するし。
まあ、可変個引数にしたい場合、(Lisp流儀だと)仕方がないわけだけど。
高い低いというより目的に合っているかどうかだな。
22 :
デフォルトの名無しさん :01/10/12 13:12
なるほど コンパイルして実行してみたらスタックエリアオーバーフロウ みたいな?
>>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 ただ単に暴走してるだけなんじゃないのかなぁ?、って事なんだけど。
なんでWindowsの話?
30 :
デフォルトの名無しさん :01/10/12 23:18
シンプルデザイン(Simple Design) いつでもシステムは出来る限りシンプルに設計されるべきだ。余分な複雑さは見つけ次第取り除かれる。 リファクタリング(Refactoring) 2重コードを取り去り、コミュニケーションを改善し、単純化し、柔軟性を加えるために、プログラマは、システムの動作を換えることなくシステムを再構成する。
31 :
デフォルトの名無しさん :01/10/13 01:00
>>27 バカだなお前
回線切って考えてから
首吊って氏ね
/ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄\
.∧_∧ |
>>31 Ruby厨な人さぁ こんなレスばっかりしてるから |
( ´∀`)< 厨房って言われちゃうんだよ |
( ∧∧ つ >―――――――――――――――――――――‐<
( ゚Д゚) < おまえのことを必要としてる奴なんて Ruby使いにすら |
/つつ | いないんだから さっさと回線切って首吊って氏ね |
\______________________
>>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のソース落ちてるから自分でヤホー検索して拾って調べるのだ。
Schemeで実用的なアプリケーションなんか作れないだろ。 いまどきSchemeなんて時代遅れ。
49 :
デフォルトの名無しさん :01/10/13 12:37
∧_∧ / ̄ ̄ ̄ ̄ ̄
( ´∀`)<
>>48 オマエモナー
( ) \_____
| | |
(__)_)
50 :
デフォルトの名無しさん :01/10/13 12:41
>>48 ここはRubyなんてやってる超初心者の来る所では無いのだ。
己の恥に、気付く前に退散しろなのだ。
違いますか? じゃあ、実用的なアプリケーションを挙げてみてください。 何もないでしょう(嘲笑)
Schemeごときが「プログラミング言語」って呼ばれちゃいけない、 と思うんですよ。
53 :
デフォルトの名無しさん :01/10/13 13:04
>>17 を拾ってXlisp-statで実行してみそ
Schemeは方言がきついので貴方にScheme上で
>>17 のソースを
実行するのは無理。
54 :
デフォルトの名無しさん :01/10/13 13:07
Scheme自体が、すでに実用的なのだが何か?
放置できない人はアホ。ウンコ。鼻毛。エスパー伊東。
言語自身が実用的ってどういう意味ですか???
>>Ruby初心者
今A.Iダッチワイフちびオメコちゃんのプログラムを
DrSchemeで書いてるから、もうちょっと待ってね!
>>55 放置しちゃ可哀想でしょ?
折角Schemeに嫉妬してるんだから・・・
反論の余地が大きすぎて何を言ったらいいかわからないので放置 ってわけでもない人は修行が足りません。
>>58 やってやって♪そしてここにコピペして〜
今Schemeやってる暇無いのよ(泣)
早くSchemeに本格以降したいです。
Schemeの開発こそ、コンピュータ・サイエンスの典型的なセンスの 一つではないかと
>>58 ソース結構でかいからコピペは無理なり
どっかにアップロードして下さい。
>早くSchemeに本格移行したいです。 御変換すいません。
68 :
デフォルトの名無しさん :01/10/13 16:05
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!
SCHEMEって名前はねー。 MITのAI LAB.で作る言語は CONNIVER とか PLANNER とか 「考えるもの」系の名前が 伝統だったんで、 「SCHEMER」とつけようとし たら、ファイル名の制限 (6文字+3文字)でSCHEMEに なっちゃったってスチール 君が言ってた。
とりあえずシェーマ−だと思う。 叩かれ覚悟のカキコ!
>>71 CONNIVER も PLANNER も 6 文字超えてるやん…
いい つっこみだけどMITとPLTの現場環境が違うとか? なんで みんなsageてんの?
解った^お^ 宝石君が来るからだ
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と省略されてるみたいです。
確かに、これじゃ、読めないわな
>>77 おー、そういやガッコのディスクあさってたら
PLNR.X っていうファイルがあったけどあれは
Planner言語ダッタのカー
SHRDLUっていうディレクトリの中にあった。
>>44 をコピペしたらDrSchemeで走っちゃった^^;
HDがカラカラ言ってる
誰か止め方教えて
Ctrl+Alt+Deleteで逝ってよし 始めて走った
Allegro アンインスト決定!
>>80 放置
>>81 いや〜んProxyはねてるぅ
GEDANKENって何ですか?
ジサクジエンです。 GEDANKENて言うLisp関連の何かがあるのかと思いました^^;
88 :
デフォルトの名無しさん :01/10/14 00:53
ちょっとageさせて下さい。 無限ループの終了方法が良くわかりません。 要操作方法のヘルプ日本語化→DrScheme
89 :
デフォルトの名無しさん :01/10/14 01:05
>>44 の様な処理をブラウザ立ち上げたまま
行うとDrSchemeの窓も閉じなくなる程OSが重たくなります。
かなりのハードウェアリソースを消費していた様です。
おれの自作SchemeではDOS窓で軽快に無限ループに陥ってるよ。 終了はCtrl+C
91 :
Tamitu :01/10/14 01:31
>41
別にWindowsで走って更にMacで走ってUNIXでまでも走る
必要無いからじゃないの?
XLispにしろDrSchemeにしろ ある目的の為に世界で一番優れた
アルゴリズムを見つけ出すのが目的の1つな訳だから・・・
javaやってる人は、ネットしかしない人を、相手にしてあげて。
>>90 Uploadして直リンは、礼儀かも
>>91 デバガとかインタフェースがなってないから無理よ。
まだ自己満足的な実験対象でしかないんで。
今の所8086でも動く。
気が向いたら公開するかも。
>>89 Windowsはschedulerがあまり賢くないから、
暴走するthreadがCPUを独占する事が良くある。
;; 嘘みたいな話だけど、priorityが固定なのだ…
;; スレ違いでsage
>>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に喧嘩を売るのだ
どれどれ見せなさいなのだ
自己満足は他己満足なのだ
>>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)
こんな感じで。
>>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とかの時には毎回チェックがいるぞ。もっと遅
くなる。
>>100 あ、もしかして自分でヒープマネージャを作って、
alignmentをあわせるようにするってことですか?
普通にnew/malloc使うこと考えてた・・・
まちがいた。 typedef union _obj { struct _pair *pair; struct _symbol *symbol; ... } obj; は typedef union _obj { struct _pair pair; struct _symbol symbol; ... } obj; のまちがい。すまそ。
>>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)
>>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は馬鹿トロイのか
>>107 ありがと。根本的に自作Schemeを書き換える必要が出てきました。
遊び処理系だから別に良かったんですが、、、
consセルで16バイト(car/cdr/type/virtual) しかもその都度newしてたんで。
よく考えたら、わざわざマスク取る時にcons->carにする 必要無かった、、。 >103 #define CAR_UNSAFE(x) (*(obj*)(((char*)(x))+offsetof(pair,car)-1)) なんでここで-1してるの?って思ったら、 pair型を前提としてるからか。
>>107 heapの最後のページをmprotect()で書き込み禁止にしとけば、if文は不要と思
われ。(RISCのバスエラー使うぐらいなら、これも使ってよいでしょー。)
consは、だからコンパイルすると3-4命令くらいかな。(heap_ptrは普通レジス
タにグローバルに割り当てる。)
>>108 さすがBASIC厨房。
Javaのような静的型付き言語だと、ダウンキャスト時以外
型チェックの必要がないのだよ。だからtagもあまり重要
でない。
>>109 virtualでやるのはそんなに悪くない選択だぞ。ただfixnum
演算でゴミが出まくるようだと、ちとつらいが...
113 :
デフォルトの名無しさん :01/10/14 05:28
なるほどねえ。バイトアラインメントを利用するのか。 consの使用量が2/3(9〜12byte->8byte)になるなら、 やる価値あるかも。
>>112 >virtualでやるのはそんなに悪くない選択だぞ。
でもnewだと遅いよね。
Pairクラスのvoid *operator new(size_t)をoverrideして、自家製の
アロケータに入れ替えちゃうのが良いと思われ。
>ただfixnum演算でゴミが出まくるようだと、ちとつらいが...
±1000くらいはあらかじめ割り付けて、配列に取っとく。
結果がその範囲なら、割り付けずに配列の中の値を返す。
んー、CISC(x86)onlyだったら、8バイトalignで、下3bitにTAG付けるのがベストかな。
なんつーか、LISPerは処理系の実装テクまで話し合うのねん。
3bit すべて型情報 でGCが stop and copy か、 2bit 型情報で、1bitGCに割り当ててGCをmark-and-sweepにするか。
>>117 mark and sweepでも、オブジェクト内にマークビット持つ
必要はない。むしろ外にビットマップ(orバイトマップ)で
持った方がGC時にキャッシュを汚さずにすんで速い。
>>113 スペースよりむしろ速度に効果大。メモリアクセス回数が
激減するので。
>>117 mark-and-sweepだと移動が無いから速いでしょう。
でもフラグメントが・・
これを踏まえると、
余裕があったら配列関係(文字列、シンボル、...)の時はstop and copy
consやらその他の時はmark-and-sweep
でしょうか。
>>118 >外にビットマップ(orバイトマップ)
これは良い考えですね。
いままで思い付かんでした。
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
>>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 だとそれは必要ないんじゃないの?
ポインタを全部フックしておくやり方は一部の実装では使われているが、
そういうのは大抵遅いし、全体としては少数派なような。
>>122 この問題は致命的な割に処置が甘くなりがちな気がする。
というか、全く処置を行なってない処理系がありそう。
実行速度に気を取られ、開発初期段階からメモリブロックを
大きく確保しすぎて、偶に起動されるgcによる破壊に気付かず、
「原因不明のバグ」としてしまうケース。(w
127 :
デフォルトの名無しさん :01/10/14 13:49
>>125 同意。いかにもシロートなやり方。
処理の途中でGCが起きるなんて当たり前でしょーが。
Schemeのdefine-syntaxとかsyntax-caseとか、 SCMでもDrSchemeでも "unbound variable" なんですけど…。 どの処理系なら実装してるんでしょう? 解説ページもあんまりないし、一般的じゃないのかなぁ。
130 :
デフォルトの名無しさん :01/10/14 17:33
でもconservativeGCって気持ち悪いんですけど。
継続について詳しくかかれている資料ありませんか? 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がカラになるの?
???
>>131 プログラミング言語scheme ピアソン・エデュケーション
ケント・ディヴィグ著 村上雅章訳
↓コレが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の場合はどうするの?
>>135 あ、ごめんなさい。
okとダメなの、逆でした
138 :
BASICER :01/10/14 19:00
>>132 なんかリアルタイムマルチタスクの処理の一つが放置されているのだ
>>136 Cで書くというやり方に固執する場合、
C処理系になるべく依存しないようにするには、
GC対象のオブジェクトはすべて、
ソフトウエアスタックや特定の大域変数から
たどれる場所に置いとく必要がある。
CのスタックやCPUレジスタをGCが直接見て、
しかもconservativeでないやり方も
当然ありうる。GCが見るルートはあらかじめ
決めておく。オブジェクトが動くかも知れない
ことを、プログラマがちゃんと意識して書く。
Lispコンパイラを使ってライブラリを
Lisp自身で書くなら、特段の配慮は必要ない。
スタックフレームのレイアウトやレジスタの使い方は
コンパイラが当然知っているから。
GCまでLispで書くのはかえって面倒だろうけど、
Lisp関数ライブラリやインタプリタは
Lispで書くのが当然いちばん楽。
>>129 結局見つからないって事は、
defmacroの方がつぶしが効くからだな。
継続のこの動作がやっぱり理解できません (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 どうしてココで無限ループに陥らないのか。
(cc1 #t) したときにcc1に束縛されている継続は、 引数をただ返すだけの継続だよ。 (call-with-current-continuation (lambda (x) (set! cc1 x0))) が(begin)の中に入ってる絵を想像してるんじゃないの?
前者を補足すると、「引数を返してインタラクティブ環境に戻る」ね。
>>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)は呼び出すたびに違う値を返す関数だから。
DrSchemeはわかりやすくていいんだが、Windows98だと1000回くらい繰り返す再起処理をステップ実行させたときにリソース食いすぎてOSごとおちることがある。 だもんで、ドスパラでWindows2000のマシンを注文した。ついでに17インチ液晶モニターも。15マソの出費だ。 こう書くとかならず「Linux使えやゴルア」というカキコがあるが、LinuxなんてCとGuileとviとEmacs Lispが使いこなせないとまともに使えない。 わかんないことがあるとすぐ「ソース読めゴルア」の世界だし。 漏れはSchemeの勉強がしたいだけだしSchemeに集中したいので、余計な作業が増えるのはいやなのだ。 sage.
Winなんて『何が使いこなせても』まともに使えない。 セキュリティパッチが出てないか頻繁にチェックしないといけないし。 ネットワークの設定変えただけでリブートしないといけないし。 わかんないことがあるとすぐ「インストールし直せゴルア」の世界だし。 漏れはSchemeの勉強がしたいだけだしSchemeに集中したいので、余計な作業が増えるのはいやなのだ。
まずは、返信ありがとうございました。 > (begin)の中に入ってる絵を想像してるんじゃないの? 引数を返す継続と言うのが分かりません。 (begin)の中と外では動作が違うということですか? もし、違うとしたら、それは必然的にそうなるものなのか、 例外としてそうするのか、教えてください。 > さっきreadしたものは関係ない。 継続は、評価すると束縛しなおさない限り、 普通の実行コンテキストと同じように変化しつづけるものということですか? #他言語のgoto先のラベルみたいに。
s/#他言語のgoto先のラベルみたいに。 /他言語のgoto先のラベルみたいに、一定位置にとどまりつづけるものではなく。/
DrSchemeの話ばかりでてるが、 MIT Schemeはどうなん?
152 :
デフォルトの名無しさん :01/10/14 21:49
つまりね、 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"))) だと連続性があるから、ループになるわけ。
>>139 説明がいまいち掴めないんですが、
結局
>>122 の後者の方法を行なうって事でいいんですか?
>CのスタックやCPUレジスタをGCが直接見て、〜
のあたりも良くわかりませんでした。
簡単にCのスタックを辿ることが可能なんでしょうか?
で、最後のLISPonLISPの話はわかりました。
>>153 ごめんなさい、そしてありがとう。
疑問が一気に氷解しました。
トップレベルとはその名のとおり、トップレベルで、
さらに上にrootがあるわけではないってことですね。
それぞれの手続きがルートと言うことで。
156 :
デフォルトの名無しさん :01/10/14 23:31
157 :
デフォルトの名無しさん :01/10/15 00:10
>>145 正直、そこまでしてSchemeに集中したいというのはスゴイと思った。
「Schemeのみ」というこだわりとカネの使い方からして老後の趣味っぽいけど。
159 :
デフォルトの名無しさん :01/10/15 01:30
下位bitのpairの型情報を0にすれば-1する必要なくなって、 速いんじゃない?マスクすら必要ないし。
160 :
デフォルトの名無しさん :01/10/15 01:42
>>118 その方法はメモリがリニアじゃない環境(8086/Palmなど)も
考慮すると、1オブジェクト毎にセグメント探索入るから
遅くて使えないです。オブジェクトから相対的にしか見えないんで。
何か良い方法はあるでしょうか。
>>159 だからアクセス時には元々マスク
なんかしてないって。
pairのタグが1だとして、嘘アセンブリ言語で書くと
load r1, [r2 - 1] ;r1<-car(r2)
load r3, [r2 + 3] ;r1<-cdr(r2)
としてるだけ。
pairのタグをゼロにしても速くならんが、
fixnumのタグはゼロでないと遅くなる。
>>160 良くワカランが、セグメントごとにビットマップ
持つとかすれば良いんじゃね〜の?
ChezSchemeは確かページごとにビットマップ持ってる。
同じページには同じ大きさのオブジェクトだけ集めて。
>>154 配列で作ったスタックに自分で待避しとけば
いつGCが起きても問題は起きないし、
Cレベルでは当然そう書くと言うこと。
CのスタックやCPUレジスタまで見るのは、
もちろん簡単にはできないが、
自分でLispコンパイラ書くよりは少し楽。
>>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待ちになる。
>>163 この文脈だと
=連続性がない、だと思うんだが、どうか。
それにそれは実装依存の話ではないのか。知らないが。
>>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));
}
とかの方が良いんじゃないか、ということなんだが…
おいおい このスレ ガーベッジコレクションの入門書になるよ
Schemeのlexical rule、マトモに実装している処理系ってあるの? たとえば、+で始まる識別子へのバインド (define +v 100) vscheme : 通る DrScheme : 通る rhizome : 通らない r5rsを読むと通らないのが正確みたいだけど
すみません。 しょうもない質問なんですが、LispとSchemeやってる人は何と呼ばれるんでしょう? Lisper, Schemerでしょうか?
171 :
デフォルトの名無しさん :01/10/15 12:27
DrSchemeの日本語入門書早く出ろ。 解説サイト見ながら実行するとハードディスクがけたたましくて かなわん
>>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だっけ?
当方北海道
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 いや、そういうことじゃないんだが。
識別子 = <頭字> <後続文字>* | <特殊な識別子>
頭字 = 文字 | 特殊な頭字
文字 = a-z
特殊な頭字 = !$%&*/:<=>?^_~
特殊な識別子 = + | - | ...
ピリオドで始まる識別子は ... のみで、他のピリオドから始まる
トークンは認識できないはずなんだが
ピリオド>あ、ピリオド等
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とかは、すべての処理系で名前と見なされ
るとは限らない。しかし、処理系はこれらを名前と見なしても良い。
>>182 >ところでここはage進行で良いのか?
質問ある人はageるんだし、どっちでもいいんじゃない?
最近はカキコも多いし。
>>183 thx!
R5RSにバージョンなんてあったんですね。
しかし、私が参考にしている訳版はバージョン表記が無いです。
いくつなんだろ
186 :
デフォルトの名無しさん :01/10/16 02:32
>>185 バージョンじゃなくて、R5RSの
2.1 Identifiersという節のことです。
string->symbolとか標準関数にあるから、 別に+vがあってもいいと思うけど。 なんでもかんでも文字列にする ->stringとか書きたいし(w
そういうことですか。ありがとうございました。 最低限識別子となりえるものだけ定義しているんですね。 そうなると、できる限り多くを識別子と扱えるようにする方が良いですね。
189 :
デフォルトの名無しさん :01/10/16 03:34
昔のScheme(R3RSのころ?)だと、1+と-1+という 標準関数があったと思う。
>>182 autoでも、&でアドレスを要求しちゃうとレジスタには割り付けられないと思われ。
なので「フック」(っていうのか?)に利点は無さそう。
自分で退避した方が速いと思われ。
Σ(゚д゚lll)ガーン
>>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、という感じになってしまう気がするのですが。
>>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;
}
こういうことじゃない?
× char* heap[SIZE_HEAP]; ○ char heap[SIZE_HEAP];
>>195 その通り。
exactなGCで無いと使えない技術と思ってよし。
>>196 pairやsymbolと違ってfixnumは即値で表すのだ。
だからfixnum演算ではメモリアクセスが全く起きない。
ゴミも出ない。
>>198 うわっ、やっちまった。
保守的マーク&スイープでこの仕組み実装しチャタヨ
うーむ、いまさら直す気もおこらないし、
超保守的GCって事でいいやヽ(´ー`)ノ
>>194 ((call/cc call/cc) (call/cc call/cc))
ベクトルの大きさを変更する方法って無いですか?
>>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
とかやるよかずっと早い気が。
結局ループの時のカウンタ等にポインタ辿るのが
嫌だ、という事では?
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 Schemeには無いね。
Common Lispのadjustable-arrayなら大きさを変えられる。
またはfill-pointerつきのvectorとか。
>>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あった方が良いだろ。
>>212 値が30ビットで表せない場合(けっこう稀だと思う)だけ
別の表現(bignumとか、ヒープに割り当てた32ビット値への
ポインタとか)にすれば、ほとんどの場合は速い表現が使え
るよ。
Win API呼び出す前にはどうせ型チェックするんだし。
214 :
デフォルトの名無しさん :01/10/18 01:50
>>213 希な訳が無いだろー(w
Windowsとの直行性を考慮するなら最低でも32bitは必要。
個人では膨大なAPIをラップするだけのライブラリなんて作って
られないから、恐らく直接DLLを叩きたくなるだろう。
Windowsで使われる定数には0x80000000辺りを使う事が沢山ある。
ポインタ値としても。
これらをいちいち場合分けして変換する?
型チェックについてはLISPコード側でいくらでも対応できる。
>>211 なんで2bitがいいの?
RISCプロセッサ使用者数なんてたかが知れてるんだし、
x86系にあわせてもっとフラグビット広く取った方が良くないか?
まあこういう議論はほんとはどうでもいいんだけど、実際使う環境下で 妙な制限のある処理系って嫌でしょ?メンテナンスも大変そうだし。 作る事が目的ならそれでいい。
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バイトアラインメントだと思ってたのだが。
>>217 いや、4バイトにこだわらなくても良いでしょ。
3bitで8バイト、4bitで16バイトなら許容範囲じゃないの?
いまどきメモリ1G搭載してるPCなんてざらにあるんだし
この辺の話は価値観、というか使い道によると思われ。 さらに、設計と実装に割ける時間。
>218 >いまどきメモリ1G搭載してるPCなんてざらにあるんだし こういう意見は聞きたくないなあ
もちろんfixnumのタグ2ビットに限る必要はない。 また最小のオブジェクトが8バイトアラインでも 3ビットに限る必要はない。 例えば、 下2ビットが00ならfixnum else 下3ビットが001ならpair ... else 下4ビットが0001なら(もっとサイズがでかい型) などというencodingも可能ではある。 つまり「下4ビットxx00はfixnum(xはdon't care)」とか。 これならメモリは特にムダにならない。
>>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), ...);
とかしてやれば良い話と思われ。
>222 >APIを呼び出すときに一律32bitに直しちゃえば良い話。 しちゃえば良い話なのか・・?
>>220 いまは、多少メモリを無駄遣いしても、
早いほうがいいっていう意図で書いたんだが。
べつに、1Gフルに使い切れって言うわけじゃない
メモリを無駄遣いしてもいいってのなら、 consを何がなんでも8バイトにする必要もないな
>>223 >> APIを呼び出すときに一律32bitに直しちゃえば良い話。
>しちゃえば良い話なのか・・?
その後ろも読めよ(W
理解できなかったか?
>>225 >メモリを無駄遣いしてもいいってのなら、
>consを何がなんでも8バイトにする必要もないな
でかくするとメモリ転送量が増えて遅くなるってば。
局所性も悪化するし。
なんででかくしたいの?
ここで話されているハイレベルな方々は.NETのCLRへのコンパイラを 作る予定はありませんか?
>しちゃえば良い話なのか・・? 律儀に変換をやってくれる門番が適切な場所に居れば いい(=速度とか以外の問題は無くなる)のでは? 「適切な場所」がどこか?は、静的に割り出し可能だよね? それこそDLL呼び出す所とか。
229 :
デフォルトの名無しさん :01/10/19 03:20
>>227 CLRのバイトコードってどんなの?
tail recursiveな関数呼び出しって可能?
Javaのバイトコードだと無理だよね。
>>227 それは、Haskell, C--をやっていたハイレベルな人達がやっています。
Simon Peyton Jones!
HotDogは、なんかまだbugyyっつってたよ。
bugyy → buggy
エロホン?
234 :
デフォルトの名無しさん :01/10/19 23:45
(エロホンp HotDog) =>nil
235 :
デフォルトの名無しさん :01/10/20 00:39
JITコンパイラのScheme処理系ってありますか?
236 :
デフォルトの名無しさん :01/10/20 18:12
kawaは?
なるほどkawaか… うーんと、自分で直接ネイティブコードを吐くやつ、とい う意味だったんですが…
238 :
デフォルトの名無しさん :01/10/20 18:47
239 :
デフォルトの名無しさん :01/10/20 20:00
240 :
デフォルトの名無しさん :01/10/20 20:10
241 :
デフォルトの名無しさん :01/10/20 20:16
lisp系ってコンパイラさえあれば、 簡単に実行時でもいつでもコンパイルできると思うが。 S式を動的生成して、普通にevalする代りにcompile-evalする。 でもこのケースはバイトコードコンパイルする処理系に限られるかも。
242 :
デフォルトの名無しさん :01/10/20 21:29
いくらよ?>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
247 :
デフォルトの名無しさん :01/10/21 01:06
コンパイルしてgcを完全に取っ払う事って可能?
制限付きで可能。>247 全部は無理。
249 :
デフォルトの名無しさん :01/10/21 01:17
>>247 漏れは246ではないが
コンパイルしたコードがゴミになったらどうするか、
ということかと思われ
トップレベルから入れた式は、define以外すぐゴミに
なるよね。
コピーGCだと、コンパイルコードもコピーされて動くんですか?
>>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なんて知ってる奴いるのか
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みたいなの実装するのと大差無い気が。
まだ実装してないが。
おれもマクロの実装はたいしたこと無いと思う。 マクロ定義自体はSchemeで書けばいいんだし。 proper tail recursionがちゃんとできれば、 継続も自然とできると思うがなー
継続も大変だと思う。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のマクロって仕様書厳密に読むと 「前もって展開はできない」って解釈できない? なんかそんな気がしたんだけど、勘違いかなあ。
>>262 マクロキーワードが変数として束縛されたら
マクロじゃなくて変数として扱わなきゃならないけど・・・
変数のスコープが静的だと考えれば、前もって展開しちゃっても
いいんじゃない?
>261 マクロを評価(展開)するときにキャッシュにあればそれを優先させるだけ。 トップレベルのマクロに対してはキャッシュは(多分)意味が無い。 フラッシュする必要はない。必要なくなれば適当なタイミングで削除する。 起動毎に展開結果が変化するマクロについてはキャッシュを適用できない。
266 :
デフォルトの名無しさん :01/10/23 17:42
>>265 formを引数としてmacroexpandが呼ばれたときに、
キャッシュを検索する、という感じでしょうか?
form自体のcarとcdrを展開結果のcarとcdrで置き換えちゃう
ことを考えていました。
>>266 直接書き換える処理はよほどうまくやらないと危険。(昔試した。)
+オリジナルコードを後で参照できなくなる。
さらに、ほとんどの場合、展開後のコードは読めない(読みたくない)。
キャッシュが実装できない時は、macro-expandを用意して
明示的に展開してしまう方法が簡単。
268 :
デフォルトの名無しさん :01/10/24 23:18
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
ここのスレの人々はなんでこんなにくわしいんだろう。 見てて鬱になるよ。仕事でScheme実装でも作ってんのかな。 それともソレ系の研究者がたまたま集結してんのかな。 そんな人は日本に何十人もいないと思うんだが…。
>>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
276 :
デフォルトの名無しさん :01/10/25 23:00
ジャイスト??
277 :
デフォルトの名無しさん :01/10/25 23:15
>>275 漏れは名椅子戸。
嘘、実は本号。
嘘、実はDQN(藁
ヘビイストって呼んでしまった
279 :
デフォルトの名無しさん :01/10/25 23:43
メイイスト? ナイスト? 本郷=灯台?
280 :
デフォルトの名無しさん :01/10/25 23:52
2ch直りん隠しページのアクセスログの集計だと、 じ:100 な:20 本:3 ぐらいだった。 ぶぶづけ、goもいる。
281 :
デフォルトの名無しさん :01/10/26 00:21
じってなんだぁ〜 なってなんだぁ〜(泣
>>274 諦めてください(w
アッカーマン関数とか竹内関数は,停止はするけど
ループだけでなく再帰を使わないと定義できない関数
(原始帰納的でない一般帰納的関数)の有名な例であり,
引数が大きくなるにつれて,消費する計算リソースは
ループだけで定義できるような関数(原始帰納的関数)とは
比べ物にならないぐらい大きくなります.
あ、マクロのClingerさんのpage発見。 "Hygienic macros through explicit renaming" "Macros in Scheme" "Macros that work" 辺りをどうぞ。> macro-expansionな日々の方々
ナルシスト ナルといえば、ロブスター味噌煮込み定食の味はいかなるものか、 解説してください>本号の人
じ: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 はよく知らないので, 感違いしていたらすみません.
>>287 ちょっと言葉使いがアレですが、SchemeではLispと違い
symbol-functionスロットがなくて、関数呼び出しの式の最初の式も、
他と同じようにevaるのは本当です。
良い点と悪い点があります。Schemeの方がきれいですが、遅くなります。
Lispだと、functionスロットには関数しか入らないように保証できるので、
呼び出す前にチェックする必要がありません。
>>288 ありがとうございます。
言葉づかいってのは "list の (先頭の) symbol を評価" っていうところですかね。
前スレの 161 で (
http://pc.2ch.net/test/read.cgi/tech/987169286/151-161 )
>・schemeなら関数呼び出しフォームの先頭要素を普通に評価してその値を関数
>として使うから、可能
>
>・common lispだとあくまで((lambda ()) foo ...)と(symbol foo...)が関数
>呼び出しフォームなだけだから、ムリ
こういうのがあって、そうなのかと思って
>>287 みたいなのを考えたんですが、
するとムリってのは嘘ですね。OO もよく知らないんで、また勘違いかもしれないけど(藁
290 :
デフォルトの名無しさん :01/10/26 22:37
CのヘッダファイルなんかをS式に直すルーチンってないでしょうか。 windows.hなどを自動で取り込める様な。 WINBASEAPI BOOL WINAPI GetHandleInformation(HANDLE hObject, LPDWORD lpdwFlags); ↓ '(winbaseapi bool winapi get-handle-information ((handle h-object) (lpdword lpdw-flags))) これは一見簡単だけど、#ifdefマクロとか切り分けがあったら面倒臭いし。
291 :
デフォルトの名無しさん :01/10/26 22:40
>>289 eval使ってる時点で反則っぽくない?
292 :
デフォルトの名無しさん :01/10/26 23:16
>>289 ええと、少しまとめると、関数呼び出し(fn arg ...)というリストを評価する
とき、
・Lispでは、リストの先頭だけ特殊な評価法をする。シンボルかラムダ式しか
書けない。シンボルの時は、functionスロットを見に行く。
・Schemeでは、他の位置と同じように評価する。任意の式が書ける。
んで、元は(obj 'message arg ...)とLispでやるには、って言う話ね?
objに変数やら普通の式が書けるようにするのは無理。291も書いてるが、
evalを使うのはゴーインすぎる。それだとspecial変数しか見てくれないよ。
(defmacro send (obj msg &rest args) `(funcall ,obj ',msg . ,args))として
(send obj message arg ...)と書くぐらいで我慢しなはれ。
あと細かいが、ラムダ式を'(lambda ...)と書くのはやめれ。昔はリストと関
数を区別してなかったけど…
今なら単に(lambda ...)と書くのがモダ〜ン。せめて#'(lambda ...)と書いて
ちょうだい。
293 :
デフォルトの名無しさん :01/10/26 23:24
>>290 CPPにかけてからやるとかいうのはどうだろう
親切に詳しくありがとうございます。 今まで elisp しかやったことないんで、 lisp 系言語の繊細な部分がわかってないようですね。>自分 eval 使うのがゴーインという意味がよくわからないんですが、 純粋に special 変数しかみないからということですか? うーん、しかし、これ以上はもうちょっと勉強してから聞くことに しますね。なんとかスコープとか、まだよくわからんので。
295 :
デフォルトの名無しさん :01/10/27 00:00
>>294 Elispだとevalでけっこう万能かもな…
しかし、Common Lispだと、他の関数の引数やletで定義された局所変数は、
外から見えないんだよ。
あと、例えばだな、機械語かせめてバイトコードにコンパイルしないと
遅くてやってられんわけだが、eval使ってリストを評価してるようだと、
そのリストはコンパイルできないだろう?
これはfexprという技法が廃れた理由でもある。
296 :
デフォルトの名無しさん :01/10/27 00:10
Scheme のひよこレベルの話を気軽にできる掲示板ないですかね。 ここだとレベルが高すぎて遠慮しちゃう。
297 :
デフォルトの名無しさん :01/10/27 00:19
Lispギコ猫ってスレがあればオレはウケルけど。 レベルを統一してないとこがここの魅力デス。
298 :
デフォルトの名無しさん :01/10/27 00:20
遠慮せずなんでも訊け。 匿名BBSで遠慮してたら訊く場所ねーぞ。 叩かれたら笑って忘れろ。
emacs lisp だと動的スコープなので eval でもできてしまうということですね。 lexical scope っていうのは、例えば let 内で呼び出した関数からは、 let でバインド?した変数はみえないっていう理解でいいですか? あと closure ってのもありますね。うーんよくわからん。勉強します。
300 :
デフォルトの名無しさん :01/10/27 02:45
>>299 正しい。
lexicalってのは「字面の」って意味だ。
Common Lisp(special変数以外)やSchemeでは、
letで宣言した変数は、ソースプログラムの字面で見て、
letの範囲の中でしか参照できない。
closureはとりあえず「関数のこと」と思っていて間違いない。
Schemeでは、関数は全てclosureというデータで表される。
lambda式を評価するとclosureになる。
301 :
デフォルトの名無しさん :01/10/27 04:31
(define transpose (lambda (x) (apply map list x)))
302 :
デフォルトの名無しさん :01/10/27 04:38
(define inner-product (lambda (l1 l2) (apply + (map * l1 l2))))
304 :
デフォルトの名無しさん :01/10/27 14:04
>>290 こういうの作ったけど、使う?
windows-name->scheme-name
windows式の名前をschemeの一般的な名前に変換する。
ascii/unicodeを識別する、最後のA/W は 無くなる。
例)
CreateWindowEx -> create-window-ex
ReleaseDC -> release-dc
WSAGetLastError -> wsaget-last-error
最後のがwsa-get-last-errorにならないところがちょっといい加減だけど
(define (windows-name->scheme-name s)
(assert (string? s))
(let loop ((cs (string->list s)) (r '()) (isupper #f))
(if (pair? cs)
(if (char-upper-case? (car cs))
(loop (cdr cs)
(cons (char-downcase (car cs))
(if (and (pair? r)
(not isupper))
(cons #\- r)
r))
#t)
(loop (cdr cs) (cons (car cs) r) #f) )
(string->symbol
(list->string
(reverse!
(if (and (> (length r) 2) ; 〜 -a or -w
isupper
(or (char=? (car r) #\a) (char=? (car r) #\w))
(char=? (cadr r) #\-)) ; 〜A -> 〜
(list-tail r 2)
r )))))))
305 :
デフォルトの名無しさん :01/10/27 14:13
>>304 補足)
入力は文字列(windows)、出力はシンボル(scheme)。
assertはCのやつと同じ意味。省いてもいい。
reverse!は破壊的なreverse。ただのreverseでもいい。
A/W ってのは、CreateWindowExAやらCreateWindowExWの場合に
create-window-exにするって意味。
306 :
名無しさん@Emacs :01/10/27 18:00
>>300 > closureはとりあえず「関数のこと」と思っていて間違いない。
それは結構まずかろう。
>>306 まずくないよ。
Schemeではprocedureはすべてclosureとして表現される。
Common Lispでは歴史的事情から
リストやシンボルも関数として受け付けるが、
そういう汚い部分を除けば、関数は全てclosureだ。
308 :
デフォルトの名無しさん :01/10/27 21:43
>>307 ?
closureには局所環境が含まれてるだろ?
309 :
デフォルトの名無しさん :01/10/27 21:54
>>293 そうですね。一度作ったらあんまり必要ないか・・
>>340 ありがとうございます。使わせていただきます。
310 :
309=290 :01/10/27 21:55
デシタ!(・∀・)
311 :
デフォルトの名無しさん :01/10/27 21:57
>>308 うん。lambda式を評価して得られたすべての関数に含まれてる。
例えばSchemeでglobalに
(define foo (lambda (x) ...))
と定義すると、fooには空の環境を含む関数が入る。
その関数を呼び出すと、環境が切り替わって(いったん空になって)
それから引数や局所変数が束縛される。
これがlexical scopingを実現する仕組み。
312 :
デフォルトの名無しさん :01/10/27 22:02
いつのまにか話がずれてるな。
>>311 だったら、
> closureはとりあえず「関数のこと」と思っていて間違いない。
これ間違ってるじゃん。逆ならまだしも。
313 :
デフォルトの名無しさん :01/10/27 22:02
>>311 空の環境なわけないじゃん。
最低、トップレベルの環境は全部見えてるよ。
逆もあまりよくないな。 「関数は実はclosureです」 なら適切、ってとこかな。
おっと、頭に「schemeでは」がいるな。
実装はどうあれ、環境を説明する時はalistが都合が良いと思う。 ・トップレベルの環境 ((変数名c . 値c)(変数名b . 値b)(変数名a . 値a)) (define foo (lambda (x) ...)) =>foo fooを定義後のトップレベルの環境 ((foo . (lambda (x) ...))(変数名c . 値c)(変数名b . 値b)(変数名a . 値a)) (実際はfooの値は#<closure>とかにして覗けなくしとく。) ・fooの関数内での環境 ((x . 仮引数)(foo . (lambda (x) ...))(変数名c . 値c)(変数名b . 値b)(変数名a . 値a))
さらに言うならば、 関数がすべてclosureだっていうのは (define (foo bar) body)が(define foo (lambda (bar) body))の syntax sugarであるとかその辺の話であって、 仕様上関数は関数で別にあった (プリミティブ関数とかは別にclosureではない) と思ったが、どうだったかな。 実装したときは(ずっと前だけど) そんなふうに思っていた。
>>312 primitiveはclosureじゃない。
schemeでは普通、closureとはlambdaで作られたものを言う。
primitive/closure/continuationの3つは
同じ形式で呼べるというだけで、内部的には区別される。
syntaxとmacroも同様に、使うときには区別する必要が無いが、 内部的には異なる。これらは環境を持たない。
320 :
デフォルトの名無しさん :01/10/27 22:27
トップレベルの環境は自明に分かるからclosureに含まれてなくてもいいと思う。 普通closureといったら関数のコード+自由変数の記憶領域じゃない? closureとcontinuationを内部で区別するかどうかは実装しだいだと思う。 continuationは意味的には暗黙に渡されてるclosure。 ところで、実際には自由変数を持たないclosureも存在することを考えると、 primitiveとか、C言語の関数とかも含めて「関数はclosure」と呼んでも 悪くないと思う。
321 :
デフォルトの名無しさん :01/10/27 22:36
syntax sugarをプログラムの読み込み時に展開する場合、
let-syntaxで定義したsyntax sygarは実行時に存在しなくていいはず。
で、内部にあるのはdefine-syntaxで定義したsyntax sugarだと
思うのだけど、これが環境を持ってなくてよいのはまさにトップ
レベルの環境は自明に分かるからで
>>319 と
>>313 は・・・。
今ざっと読んでみたら、 仕様書にはclosureって概念はないようだね。 (和訳だけど、手続きってclosureじゃなくてprocedureのことだよね?) まあ、実装はともかく、意味論的には関数=closureの一種と捉えても 問題はなさそうだね。 俺はOO的に言うと closure、primitive、continuationはprocedureの派生物、と捕らえてるけど。 こっちも話がずれてしまったが、 最初の指摘はとにかく > closureはとりあえず「関数のこと」と思っていて間違いない ではいらぬ誤解を招くのでよくない、ということがいいたかたった。 「関数」と言われて局所環境が含まれているものを想像する者は あまりおらんだろうし、それこそがlisp/schemeのクロージャのキモな わけだから。
>>320 primitive/closure/continuationの3つをひっくるめて
'関数'と呼ぶのは賛成だけど
'関数はclosure'ってのはおかしい。
procedure?(手続き)って述語が標準であるでしょ。
それとは別に大抵の処理系では
primitive?/closure?/continuation?がある。
function?をもし作るとしたらどれを真にする?
>>321 macroは単に展開後のコードに現在の環境が引き継がれるだけだから、
それを'環境を持つ'とは言わない。
でも、マクロ定義自身に自由変数が出現した時は、 その自由変数はマクロを使用する環境じゃなくて、 マクロを定義した環境で評価されなくちゃいけないんでしょ? それって関数と同じじゃないですか?
>>313 よくわからない。
簡単なコードでいいから書いてみて。
313はオマエ
>>329 R5RSの14ページに載ってる例だけど
(let ((x 'outer))
(let-syntax ((m (syntax-rules () ((m) x))))
(let ((x 'inner))
(m)))) => outer
これってmが環境を持ってるよね?
331 :
デフォルトの名無しさん :01/10/27 23:33
関数のことと思ってよいと逝った本人だが… 単に関数(Schemeならprocedure)という言葉だけで そもそもclosureという言葉を持ち出す必要はないように 思う、という意味で「関数のことと思って良い」と書いた。 確かに「空」という言い方はちょっと変だった。 特定の実装に捕らわれた言い方だった。 トップレベルで定義した名前にはR5RSでいう interactive environmentが閉じ込められてる。 primitiveがclosureでないというのは変な気がする。 closureであっても全くおかしくない(というか、 実装ではそんな区別はしない)と思うが。 また、Scheme自身で書いたprimitiveはどうなる? 漏れが書いた処理系ではevalがSchemeで書いてあるが? (当然closureになっている。) Common LispとSchemeで事情は変わらない。 CLtL1の頃はlambdaというシンボルで始まるリストや 関数定義を持つシンボルもfunctionpで真になったが、 これは訂正された。 うーん… すべての関数(procedure)は、概念的に (環境, 仮引数, 本体の式)の組と考えることができる。 この組をclosureと呼ぶ、ってのはどう?
>>330 展開後のコード
(let ((x 'outer))
(let ((gen0000 x))
(let ((x 'inner))
gen0000))) => outer
333 :
デフォルトの名無しさん :01/10/27 23:38
>>323 procedure?(手続き)って述語が標準であるでしょ。
それとは別に大抵の処理系では
primitive?/closure?/continuation?がある。
function?をもし作るとしたらどれを真にする?
そんな処理系知らないけど…
Schemeコンパイラでコンパイルした関数はどれになるの?
もし作るとしたらすべてのorにする。
だってprocedure?の同義語でしょ?
334 :
デフォルトの名無しさん :01/10/27 23:41
>>322 「関数」といったら局所変数が含まれてるものも
含まれてないものも引っくるめて思い浮かべるのが
普通だろう。
(define ((compose f g) x) ((f g) x))
で、(compose car cdr)が返す物は関数じゃないのか?
335 :
デフォルトの名無しさん :01/10/27 23:45
>>331 なんとなくわかったが、普通の人は「関数」と聞いて
環境を含んでるとは思わない(と思う)から、
わからない人に対する説明としては意味がないと思う。
> closureであっても全くおかしくない
closureであってもおかしくないのと
primitiveがclosureだとは限らないのは
別のこと(排他的でないこと)でしょ?
だから、
> また、Scheme自身で書いたprimitiveはどうなる?
に対しては「どうでもよい」
あと、
> 実装ではそんな区別はしない
効率を考えたらする可能性も大
> すべての関数(procedure)は、概念的に
> (環境, 仮引数, 本体の式)の組と考えることができる。
> この組をclosureと呼ぶ、ってのはどう?
好きにしたらいいと思う、ただ利点がわからない
AがBであるからといって
BがAであるとは限らないんだが……
>>334 それだったら、common lispで関数とclosureを分けて説明する必要が
ないと思うんだが。
>>325 実装的にはリネームするのは分かるのですけど、
意味的にはマクロが環境を持ってると思いませんか?
とくに313さんはトップレベルの関数も環境を持ってると主張してますし。
>>333 primitive?/closure?/continuation?
は内部表現を限定したい時に必要。
例えばインライン化などの切り分け。
(if (defined? 'foo)
(if (closure? foo)
(inline-expand foo)
...))
>Schemeコンパイラでコンパイルした関数はどれになるの?
実装によるとしか言えない。
>>337 いやだから、あれは考え方として書いたのであって、実装上は
どんな事になってても、つじつまさえあえばどうでもいい問題。
マクロも、環境を持つ事はややこしくなるだけで、
特に利点は無いと思う。
340 :
デフォルトの名無しさん :01/10/28 00:05
効率を考えて「環境を閉じ込めた関数」と「閉じ込めていない関数」を 区別する実装はあるかも知れないが、そんな細かい実装上の区別を 初心者に押し付けてどうする? 「すべての関数は環境を内部に持っている」と言った方が簡単だし 概念的には正しいだろ?
341 :
デフォルトの名無しさん :01/10/28 00:10
ああ、ちょっと待って。 食い違ってるのはこれかも知れない。 1.closureとは関数の実装法の1つである。 closureの形の関数と、それ以外の形の関数がある処理系が多い。 2.closureとは、「環境と式の組」という概念である。 Schemeやlexical scopeのLispで、すべての関数はclosureと 見なすことができる。 漏れはずっと2のつもりでclosureという言葉を使ってるが…
>>337 >とくに313さんはトップレベルの関数も環境を持ってると主張してますし。
トップレベルの関数にも環境はあるよ
(define bar #f)
(define (foo) (bar))
(define (bar) #t) ;<=この定義で(define bar #f)は隠される。
(foo)
=>#t
とできるって事は、環境が存在するって事。
343 :
デフォルトの名無しさん :01/10/28 00:15
>>342 guile> (define foo (lambda (x) (car x)))
guile> (foo '(a))
a
guile> (define car cdr)
guile> (foo '(a))
a
あれ?
>>343 guileは色んな点でschemeの仕様とは食い違う。
詳細は知らないけど。
>>341 突き詰めれば同じことだと思うけど……
伝統的には1.だよね。
2.の意味だと、closureという言葉が意味を失うから。
closureとclosureでないものを区別する必要がなくなるからね。
R5RSでも、「lamda式は手続きに評価される。
lambda式が評価されるときに有効な環境は手続きの一部として
記憶される。」(以下評価時の手順)と、ニュアンス的には1な感じだね。
>>345 「ニュアンス的には2」のまちがいじゃないの?
「lambdaはそうだがprimitiveは違う」とか
わざわざ言う必要ないんでは。
なんでclosureにこだわってるのか知らないけど、
わからない人にはprocedureでいいんでしょ?
primitiveはprimitive。
primitiveの実装がclosureだとしても、それは原始言語での話。
>>346 primitiveとlambdaを比較対象にするのはおかしい。
lambdaはただの構文上のシンボル。
>>342 (define bar #f)
(define-syntax foo (syntax-rules () ((_) (bar))))
(define (bar) #t) ;<=この定義で(define bar #f)は隠される。
(foo)
=>#t
ですよね?
マクロもトップレベルの関数も意味的には環境を持ってるけど、
実装的には持ってないみたいな・・・。
>>341 の2の意味で関数がclosureというのは全然問題ないと思う。
1の意味でprimitiveとlambdaで作った関数を区別して実装した方が
(primitiveはclosureとしない方が)効率的か?というのが問題になってたと思うのだけど、
ネイティブ関数とschemeでかかれた関数との区別を混同してる気がする。
>>348 多分、シンボルと環境の関係を理解してない気がする。
351 :
デフォルトの名無しさん :01/10/28 01:29
>>347 おれがこだわってるんではなくて(苦笑)
元々
>>299 の 「closureってのもありますよね。
うーん。よくわからん。勉強します。」
に対するおれの答え方が悪かったらしくて話がこじれたのだ。
「SchemeやCommon Lispでは、全ての関数はclosureであると
考えても概念的に不都合は無いんだから、特にclosureなんて
言葉は気にしなくて良い。単に『関数』または『procedure』
という言葉だけ使ってれば良い。」とでも言えば良かったか。
しかしこんな長いの書きたくない。
んー、また初心者を遠ざけたかな。
不都合はあると思うけど。少なくともCommon Lispでははっきり区別される。
>>348 alist = 環境みたいに考えると、
「環境を閉じ込める」=「alistを持つ」
となっちゃうが、これはScheme的には正しくない。
具体的な実装に近い言葉で言うと、
・binding constructは新たな「環境オブジェクト」をつくる。
・トップレベルの関数は、みな同一の「環境オブジェクト」を閉じ込める。
・defineは「環境オブジェクト」の名前表の先頭に
新たな名前の束縛を追加(prepend)する。
と思えば良いのではないか。
(define bar ...)
(define foo (lambda ...)) ;; <- この関数には環境が閉じ込められる。
(define bar ...) ;; <-上で閉じ込めたのと同じ環境の
名前表の「先頭に」barの束縛を追加する。
なので、fooに閉じ込めた環境のなかで、barがshadowされる。
こういう風に考えないとinternal defineが
複数個あるときの解釈がうまくいかない。
354 :
デフォルトの名無しさん :01/10/28 01:39
>>352 はっきりと区別されるとは?
CLtL Chap. 3. Scope and Extent
The rules of lexical scoping imply that lambda-expressions appearing in the
function construct will, in general, result in ``closures'' over those
non-special variables visible to the lambda-expression.
「(lambda式で作る)関数は一般に全てclosure」と書いてあるように読めるが…
355 :
デフォルトの名無しさん :01/10/28 01:50
読み違いでしょ。
357 :
デフォルトの名無しさん :01/10/28 01:57
358 :
デフォルトの名無しさん :01/10/28 02:03
>>352 区別しなきゃならないのはどういう場合ですか?
'(lambda ...)の書き方はクロージャーじゃないけど、
CLtL2になって許されなくなりましたよね?
>>357 ここでのfunctionは、function special formのことだ。
原文をよーく見てみ。フォントが違ってるだろ。
closure の元ネタふった 299 ですが. 個人的にはもう何が何だか意味がわかりません.(藁 ここでの会話が理解できるようになるまで勉強します.(藁
>>353 「binding constructで新しい環境を作ったり・・・」
などの操作を含めてalistを持つとみんな思ってるんじゃないですか?
ところで、internal definitionはletrecと等価で、
letrecでは同じシンボルが2度出現することは許されませんが、
その例は正しく動かなくてもいいんじゃないですか?
362 :
デフォルトの名無しさん :01/10/28 02:12
唐突だけどscheme推薦図書 1)計算機プログラムの構造と解釈 第二版 4600+税 ISBN4-89471-163-X 2)プログラミングSCHEME 3000+税 ISBN4-89471-226-1 両方とも(株)ピアソン・エデュケーション。 さらに2つとも(英語だけど)ネット上で全部読める。 この2冊はお金だして買ってもいいと思った。 1)は色んな所でがいしゅつだけど必須。
363 :
デフォルトの名無しさん :01/10/28 02:19
>>361 同じシンボル2回という話ではなくて、
前方参照がなぜできるのかという話。
まあletrecにいちいち変形していると考えてもよいけど。
>>362 僕もこの2冊は買ってもいいと思う。
特に1は面白い。
2は正確には「プログラミング言語SCHEME」。
>>363 実際にbarの値を参照するのはfooを評価したときだからでしょ?
366 :
デフォルトの名無しさん :01/10/28 02:22
>>359 「function構文の中のlambda式」は関数すなわちclosureに
なるってことでしょ?
で、そうでないlambda式はただのデータだが、そんなことは
ここにいちいち書いてない、ってだけでは。
じゃないとすると、closureでない関数ってどうやって書くの?
368 :
デフォルトの名無しさん :01/10/28 02:25
>>365 (define outer (lambda ...
(define inner1 (lambda (x) (inner2 ...)))
(define inner2 (lambda (x) ...))
...)
inner1がalistを閉じ込めると考えたら、
その中にinner2は含まれていないはず。
>>362 の二つは英語で web で読めますが, 日本語で
学習に使えそうな web 上の情報ないですかね.
初心者用ではなく中級くらい以上のがなかなかなくて.
やっぱり本買うしかないかな.
意味不明。 普通に関数定義すれば、それが関数だろ。
買っても読まないとダメっていってるな.. やはり買おう.
370>366ね。
373 :
デフォルトの名無しさん :01/10/28 02:31
>>370 んで当然それはclosureだろ。
(defunフォームをmacroexpandしたことある?)
訂正:「んで、それをclosureと区別する必要がどこにある?」
375 :
デフォルトの名無しさん :01/10/28 02:36
>374 (defun f () ()) このfはclosureなのか?
>>368 それはわかります。
alistを閉じ込めるの解釈がちょっとひねくれてませんか?
その例でいえばlambdaで新しく出来た環境全体を閉じ込めると
解釈してくださいよ。
378 :
デフォルトの名無しさん :01/10/28 02:39
なんかいつにもなく盛り上がってますな。
379 :
デフォルトの名無しさん :01/10/28 02:39
>376 もちろんCommon Lispでだよね? もしそうなら俺が間違っていた。
380 :
デフォルトの名無しさん :01/10/28 02:39
>>375 closureでないとしたらなんなの?
(いや、そういう処理系もアリかも知れないが。)
382 :
デフォルトの名無しさん :01/10/28 02:42
>>379 例えば昔なら(lambda () ())というリストを
symbolのfunctionスロットに入れとく処理系もありだったかも。
でも、CLtL2になって
「function型はconsともsymbolともdisjoint」ということに
なっちゃったのよ。
ちなみに、上の変更によりclosureをlistで表現するのもナシになった。
確かに評価できるね。。いつの間に。 (defun f (j) (let ((i 3)) (funcall (lambda (j) (* i j)) j)))
384 :
デフォルトの名無しさん :01/10/28 03:00
>>377 だったら意見が一致してると思うが...
トップレベルでも同じでわ?
一晩寝たらすっきりわかった。 単なるModel-Viewの問題だ。 たとえば、UNIXのソケットプログラミングをしてる人に対して、 socketの戻り値はなんですか? と聞いたら、 『ソケットのidだよ』と答えるでしょう。 事実としてはint型の整数であっても。 同様に、 関数型プログラミングをしてる人に対して、 (define ((compose f g) x) ((f g) x)) の戻り値はなんですか? と聞いたら、 『関数だよ』と答えるでしょう。 事実としては『環境を伴う手続き』であっても。 そういうことだね。
common lispだったら関数はシンボルの関数スロットに入ってるんだから、 (defun f () ()) のfはclosureなのか? って無意味な質問だろう。 でなんでまたその答えが「closureだよん」になるのか。
387 :
デフォルトの名無しさん :01/10/28 08:28
これの元って素人に説明しようとしてたんじゃないのか? だったら通常の言語における関数との違いを強調すべく、 closureと呼ぶ方がよいように思える。 closureはLispにおける関数だ、ならわかるが、 closureは関数だ、は混乱を招く気がするが...
すべての関数がclosureってわけじゃないよね? その辺りを分けた方がいいのでは?
389 :
デフォルトの名無しさん :01/10/28 12:19
みなさんはscheme処理系は何をお使いですか? おすすめの処理系とかありますか? # ここにいる人はみなさん自作!?
390 :
デフォルトの名無しさん :01/10/28 12:43
激しく優良かつ高レベルなすれだなぁ。
List遊びが紀伊国屋にあったんで、それ買って
みなさんに一歩でも近付けるようになりたいと
思いますage
>>389 MacCommonLisp!
391 :
デフォルトの名無しさん :01/10/28 13:55
>>386 はいはい。正確には(symbol-function 'f)だね。
これがclosureになっていると考えて「何ら不都合はない」という話。
>>387 素人には、違いを強調「したくない」。
closureという仕組みを用いる関数とそうでない関数が必要だなんて
処理系作成者を除いて知る必要はない。
そういう仕組みがあると知ってしまった人には、なるべく単純化て
「全部そうなってると思っていて何ら不都合はない」と教える。
>>388 分ける必要があるのは処理系作成者だけだろう。
補足: なるべくなら、「通常の言語」に汚染されていない人に、 変な制限のある関数でなく、 SchemeやCLのfirst-classな関数を先に知ってもらいたい。 不幸にも制限や例外のある関数の概念が染み付いちゃった人 には、closureなんて言葉を使わず 「Schemeの関数はfirst-classだ(妙な例外はない)」 と言うことだけ知ってもらうのが良いだろう。 closureという言葉を聞いて「そんなことを勉強しなきゃ ならないのか」と欝になった人には 「(first-classの)関数(を実現する仕組み)のことだと 思っていて何ら不都合はない」 「だからそんな言葉は気にするな」と言いたい。
>>392 ふむ、なるほど。
俺は素人、というと当然Cとかそれ系はやっている、
という想定だったが、その想定自体結構腐ってるな、良く考えると。
うん、そっちの言う事が正しそう。
394 :
名無しさん@Emacs :01/10/28 14:17
>>392 プログラム板で「汚染」とか言ったってしょうがないだろう。
ちょっと思想に偏りすぎだよ。
ラウンジでもいってプログラム言語勉強したことのない人に
説いてこいよ。
>>394 ラウンジじゃなくてプログラム板だからそういう事が
言えるんじゃないか?正しいプログラミングの概念、
とかを語る事が出来る程度にはここは技術板だと思って
いるのだが。
>>393 わかってもらえてうれしいよ!
2chでこんなまともな議論ができるとわ。
>>394 漏れは素人さんも歓迎。現に来てるし。
「まず、関数にはC風の関数とclosureとcontinuationがあって…」
とか言って追い返したくない。
「汚染」でムッとした?
なら「他の言語を知っちゃった人でも」と言い直す。
397 :
名無しさん@Emacs :01/10/28 14:35
語るのはかまわんよ。 だが「汚染されてる」ことを前提にしてないのは変だ。 「高階関数とかの概念知っててC的な関数を知らない」人が どれくらいいると思ってるんだ。 数学板ならまだしも、プログラム板で。 状況考えたら絶対に変だ。宗教家かバカ学者っぽい。 そういう思想を説きたいんだったら投げやりに済まさないで 最初からちゃんと説明しとけば済んだ話しだし。 個人的な意見を言わせてもらえば、「汚染されてる」って 表現自体もあまりよいとはいいがたいと思う (だって合理性の問題だし)が、これはまあ譲歩。
>>397 1.なるべくなら、「通常の言語」に汚染されていない人に…
2.不幸にも制限や例外のある関数の概念が染み付いちゃった人…
3.closureという言葉を聞いて「そんなことを勉強しなきゃ
ならないのか」と欝になった人には…
と3段階に分けた。
あんたの言う通り1は少ないかもしらん。今回の素人さんは3だ。
3相手になぜ「closureとは関数の事と思っていて良い」と言うか、
という理由を1〜3の順に説明してみたわけ。
399 :
名無しさん@Emacs :01/10/28 14:54
言ってることがよくわからない。 その3段階はexclusiveなのか。 思想を語りたいならうまいこと関数型プログラミングのスレに 誘導したほうがいいと思う。 関数型である(とみなせる)ということだけが lisp/schemeの本質ではないのだから。
400 :
デフォルトの名無しさん :01/10/28 15:23
>>399 1と2はdisjointだね。3はそうでもないが。
思想を語りたいなんて思ってない。言いたいのは、
「closureはとりあえず『関数のこと』と思っていて間違いはない」
と素人さんに言うのは、何らまずくないということだ。
「それは結構まずかろう」とかいうヤツの方こそ、
何が言いたいんだか分からないね。
「処理系の中身勉強してから出直して来い」ってか?
401 :
デフォルトの名無しさん :01/10/28 15:27
>>399 話がかみ合ってないよ。
>>392 で「汚染」とか「不幸にも」という言葉に彼の思想が
感じられるけれど、彼は別にそれを主張してるわけじゃない。
「closureは関数である」という発言がどういうシチュエーションを
意図してるかを例をあげて説明してるだけでしょ。
402 :
名無しさん@Emacs :01/10/28 15:28
403 :
デフォルトの名無しさん :01/10/28 15:32
関数の件は、「記述上は同じ風に書ける」ってだけに しといた方が良い気がする。 つまり、あえてclosureという言葉を最初から出さない。 「なんでlambdaの外側にlet書いても変数が消えないんですか? まずくないんですか?」 とか質問されたら「実はそれはclosureという概念で・・」 って切り出せば良い。不思議に思わないのなら、放っておく(w closureとは何か?と聞かれたら、普通の関数とは違う事を説明する。
404 :
名無しさん@Emacs :01/10/28 15:33
>>400 エート、だから「素人さん」が思い浮かべる「関数」が
問題になるんでしょ?
> あんたの言う通り1は少ないかもしらん。
と認めたなら、その説明が何をもたらすのかは自明だと思うのだけど。
405 :
デフォルトの名無しさん :01/10/28 15:36
closureは単に変数の寿命に関わる概念。 すべての変数は永久に消えない事が保証されているが、 参照が無くなればgcで自然に消滅する。
406 :
デフォルトの名無しさん :01/10/28 15:40
>>404 だから2や3の人が多いって事でしょ?
2や3の人向けの説明も書いたよ。
407 :
デフォルトの名無しさん :01/10/28 15:41
>>404 そんなの問題になってないと思うけど・・・。
問題は「closureを関数と呼んでよいか?」だけでしょ。
1は仮想的な反例の1つだからトリビアルでも全然問題なし。
>>403 寿命の話にclosureという言葉は使わなくても良いような。
「closureが普通の関数と違う」というのは
バイアスがかかった言い方だと思う。
Schemeの関数の方が普通で、他の言語の「普通の関数」が
制限付きの半人前の関数という見方もあるんじゃないか?
409 :
名無しさん@Emacs :01/10/28 15:45
>>406 それはわかったが、300の時点ではおかしかった。
>>407 それはおかしい。
400には、
> 「closureはとりあえず『関数のこと』と思っていて間違いはない」
> と素人さんに言うのは、何らまずくない
と書いてあるのだから、この結果として生じるものは
「素人さん」が「関数とはどのようなものであると思っているか」に
依存する。
410 :
デフォルトの名無しさん :01/10/28 15:45
「closureは関数の一種だけど、ただの関数ではない。」 でいいんでしょ? 外部に参照を持たないclosureは普通の関数となんら変わらないし。
411 :
403=405=410 :01/10/28 15:49
僕の言う「普通の関数」とはCやPascalなどの一般的な 手続き型の関数表現の事を言ってます。 なにが普通か?って議論をするつもりは無いです。
412 :
403=405=410 :01/10/28 15:50
>>410 だから「ただの関数と違う」とわざわざ強調するのは
(処理系作成者以外には)益がないでしょ、という話。
>>409 んじゃ場合わけをやり直してみる。
「あと closure ってのもありますね。うーんよくわからん。勉強します。」
と言った人が(この人個人の話でなくて一般に)、
A.他の言語の(first-classでない)関数の概念を知らない場合。
特に「Schemeは他と違う」とか「closureという機構が必要になる」とか
言う必要は全く無い。「closureなんていう言葉は気にしなくて良い。
関数のことと思っていて間違いない。」と言って良い。
B.他の言語の(first-classでない)関数の概念にはなじんでいる場合。
「Schemeの関数はfirst-classである」ということだけ知ってもらえば良い。
closureという言葉を持ち出す必要は全く無い。「closureとそうでない関数の
区別」など邪魔になるだけ。「closureは、(first-classな)関数(を実現する
仕組み)のことと思っていて間違いない。」と言って良い。
これでどう?
415 :
名無しさん@Emacs :01/10/28 15:57
もしかして「素人さん」は「関数」でも「クロージャ」でも 環境がついてくるかどうかになど自覚的ではない、って話? 「素人さん」でもC的な関数には環境はついてこないってことは 理解している、って前提で話してた。
>>413 でもCとschemeで書く場合ってスタイルが結構変化しますが。
Cのコールバックにおける引数渡しとか。
417 :
名無しさん@Emacs :01/10/28 16:01
>>414 first-classであるってのは、すなわち環境がついてくるってこと?
それを証明しないと、その説明でCプログラマに理解してもらうのは
無理なような。
でそれを証明するのはクロージャを説明するよりもっと大変なような。
どうよ。
map/for-each系の内部イテレータ関数はclosureが無いと困難。
419 :
デフォルトの名無しさん :01/10/28 16:08
>>417 それこそ相手によるが、実装を説明した方が分かりやすい
相手なら説明すれば良いだろう。
その場合も「全部closure」で不都合はない。
CLtLでは「変数の束縛は無制限の寿命を持つ(必要な期間 保持される)」
とだけ説明している。
420 :
デフォルトの名無しさん :01/10/28 16:10
>>417 Cプログラマに理解してもらいたいって趣旨だったのだろうか・・・。
こまかいことは気にしなくても問題ないってことでは?
421 :
名無しさん@Emacs :01/10/28 16:27
Cじゃなくてもいいけど、
「関数がfirst class」っていうだけでわかるような相手だったら
それこそ何も説明しなくもいいと思うが。
> こまかいことは気にしなくても問題ないってことでは?
それだったら別にどうでもよい。
>>415 にも書いたけど、
想定してた「素人さん」の多言語に関するレベルが違ったかもしれない。
前にCプログラマにlispの関数を説明したときに
「え? Cにも関数ポインタがあるじゃん」て言われた経験があったから。
lispの長所を説明するには、最低限相手にもそのくらいの知識がいると思ったので。
その場合『「全部closure」で不都合はない。』のは、
closureを説明してからの話。
422 :
デフォルトの名無しさん :01/10/28 16:45
もし、Cにも内部定義があったなら・・
423 :
デフォルトの名無しさん :01/10/28 16:49
あるところにschemeを使ってみようかなと思ってる人がいた。
偶然にもそのひとはclosureという言葉を耳にしてしまった。
「うわぁ〜schemeって大変そうだ!?」と困惑していたので、
closureは関数だと思ってればいいですよっていう、助言がなされた。
>>421 確かにCをよく知ってる人に関数型の長所を説明するのにはそれではダメですね。
関数が関数の内部でも定義できる。
内部で定義された関数からその外側の関数の変数が参照できる(lexical scope)。
関数を(内部で定義されたものも含めて)整数などと同じようにやり取りできる。
と説明するとよいのかな?
424 :
名無しさん@Emacs :01/10/28 17:05
了解した。 長々とスマソ
425 :
デフォルトの名無しさん :01/10/28 17:17
内部定義だけなら寿命は関係ないから、Cでも実装できそうだよね。 コールバック関数作って、関数ポインタで変数渡すのは書くの だけでほんと疲れるし。(グローバルに置くのは却下。) Cでそれをやらなかったのは実装が難しくなるからだっけ? Pascalにはあるのに。
426 :
名無しさん@Emacs :01/10/28 17:21
gccにはあるよ。
427 :
デフォルトの名無しさん :01/10/28 17:23
>>425 gcc拡張には内部関数があるね。
内部関数へのポインタは、
スタック上にclosureを作って、
それへのポインタを渡している。
428 :
デフォルトの名無しさん :01/10/28 17:29
SICP 4.1.7にある、「構文解析を実行から分離」(analyze) だけを実際の解釈系に適用すると、どの程度の 効率化が見込めるでしょうか? コードを原始言語側のclosureの連にするって事ですよね。 eval通さなくて済むって事だけで結構速くなるかな?
429 :
デフォルトの名無しさん :01/10/28 18:18
構文解析のときに構文エラーのチェックとかマクロの展開をしてると、 それをやらなくてもいいので随分速くなると思うけど。
>>429 なるほど。
評価もスタック無しで回せるから、確実に速くはなりそうですね。
作ってみようかな・・。
関数をclosureと同じと見なして構わないというのはSchemeや そういう構造を持つ言語でだけでの話しだよね? 一般的にそう言えるってこと?
432 :
デフォルトの名無しさん :01/10/28 19:32
>>431 まあSchemeやCommon LispやMLなんかでは、だろうね。
既にいろんな言語知ってる人なら「Scheme(等)では」
と自分で補ってくれるだろう。
初めての言語がScheme(等)の人だと、Cやなんかを後で
やったときに「qsortに渡す関数を動的に作るにはどうやるんだろう」
と悩むかも知れないね。実際あると便利なのになあ、と俺も悩むし。
Javaなら別に悩まないだろうね。closureのかわりにinstance作れば
良いから。
>>268 おそレスかつどうでもいい話だけど、1.5課のとこで、
なんで三角形の面積があれで求まるのか悩んじまっただよ。
いちおう導出できたけど、時間かかりまくり。
欝だ氏脳…
434 :
デフォルトの名無しさん :01/10/28 19:56
lispの前置記法とかって嫌われる傾向があるけど、 演算子オーバーロードの無い言語とかでも結局関数呼出しだらけ にしたら見た目はほとんど変わらなくなるんだな。
435 :
デフォルトの名無しさん :01/10/28 20:05
>>434 開きカッコが関数名の前か後かの違いと、
区切りにコンマ使うか、空白使うか、って事?
C言語 a(b(c(),d()),e());
LISP (a(b(c)(d))(e))
(LISPはカッコ自体も一応セパレータ)
>>435 C言語 a+b;
LISP (+ a b)
C言語 test?a+b:a-b;
LISP ((if test + -)a b)
437 :
デフォルトの名無しさん :01/10/28 21:44
438 :
デフォルトの名無しさん :01/10/28 21:45
(defun triangle(a b c &aux s) (setf s (/ (+ a b c) 2.0)) (sqrt (* s (- s a) (- s b) (- s c))))
439 :
デフォルトの名無しさん :01/10/28 22:55
>>438 &auxって何ですか?
letみたいな一時変数?
440 :
デフォルトの名無しさん :01/10/28 23:00
>>430 あのサンプルって末尾再帰あたりの問題はどうなるんだろ?
441 :
デフォルトの名無しさん :01/10/28 23:06
>>439 その解釈で問題無いと思われ。
(define (triangle a b c)
(let ((s (/ (+ a b c) 2.0)))
(sqrt (* s (- s a) (- s b) (- s c)))))
442 :
デフォルトの名無しさん :01/10/28 23:57
>>440 あのSchemeインタプリタ(L1)を実行してるScheme処理系(L0)が
末尾再帰を正しく扱うなら、L1にインタプリトされるScheme
プログラム(L2)の末尾再帰も正しく扱われる。
443 :
デフォルトの名無しさん :01/10/29 00:06
>>442 おぉ、なんだか懐かしい話だ。
メタサーキュラーインタプリタの利点って昔習った気がするぞ。
445 :
デフォルトの名無しさん :01/10/29 00:16
MacOSXなんですがことごとくMakeに失敗してます。 簡単に構築できるScheme環境ないですかねぇ。
Macバイナリで配布してるschemeって無い?>445
447 :
デフォルトの名無しさん :01/10/29 00:30
Classic(OS9のエミュ)用ならあるけど MacOSXネイティブが見当たらないんです。 Linuxに乗り換えようかな…
448 :
デフォルトの名無しさん :01/10/29 01:39
ここにいる詳しい人たちってみんな大学で lisp, scheme を学んだんですか? それとも自力?
449 :
デフォルトの名無しさん :01/10/29 01:51
自力に決まってるだろ。大学なんて負け犬が逝くところだ。
450 :
デフォルトの名無しさん :01/10/29 01:53
やっぱり mit くらいじゃないと lisp の高度なことなんて 教えてないんですか? 初級はどこにもあるにしても.
(某大学の研究室) 学生「ついに出来ましたセンセー! 見てくださいよ、世界最速のScheme処理系です 名付けて凄Schemeおれってスゴスギー!」 教授「今どきSchemeなんて誰が欲しがるんだ 遊んどらんで研究しろ論文書け そんなこったからいつまでたっても博士号とれんのだ」 (大学に程近い川辺) 学生「あーあ、やっぱりSchemeじゃ研究に ならんかなー 俺も来年は28だしそろそろ卒業せんと まずいよなー」 −Schemeのソースコードの入ったFDを川に投げ捨てようとする学生 学生「えいっ、こんなもの…」 −とーとつに現れる謎の女 女「待って!」 学生「え…?」 女「私はQ国のスパイ。私の国では今、優秀なScheme処理系を 切実に必要としているのよ!」 学生「なんでまた…」 (続く)
452 :
デフォルトの名無しさん :01/10/29 11:42
453 :
デフォルトの名無しさん :01/10/29 15:02
ルディ・ラッカーの「ハッカーと蟻」を読め ロボット制御のゴリゴリのC使いがLisp会社に引き抜かれて がんばる話。
457 :
デフォルトの名無しさん :01/10/29 18:49
>>456 うお、興味あり。さっそく帰りに探してみよう。
サンクス。
$B!J$=$N$H$-FMG!8=$l$?9u$$<V!K(B $B!J9uI~!"9u4c6@$NCK$?$A$,$o$i$o$i$H#2?M$r<h$j0O$`!K(B $BCK!V$=$N%G%#%9%/$rEO$7$F$b$i$*$&$+!W(B $B=w!V$*A0$O!D%(%k%7%g%U!*!W(B $BCK!V5W$7$V$j$@$J!"%P!<%P%i!&%j%9%3%U!W(B $B=w!VF($2$k$N$h!"Aa$/!*!W(B $B3X@8!V$(!D!)!W(B $B!J6/0z$K3X@8$N<j$r0z$$$FAv$j=P$9%P!<%P%i!K(B $B%(%k%7%g%U!VBT$F!*$($($$!"DI$(!*!W(B $B!J=F$r0z$-H4$$$FDI$$$O$8$a$kCK$?$A!K(B $B!V%@!<%s!*!W(B $B%P!<%P%i!V$&!D!W(B $B3X@8!V$"!*!W(B $B%P!<%P%i!V!D;d$N$3$H$ONI$$$+$i!"F($2$J$5$$!*(B $B!!!!!!!!!!$=$N%G%#%9%/$r;}$C$F!"2#ED4pCO$N%"%?%J%=%UBg:4$N=j$X!D!W(B $B3X@8!V$G!"$G$b!D!W(B $B%P!<%P%i!VAa$/!"1Q0l7/!*!W(B $BE4CK!V$I$&$7$FKM$NL>$r!)!W(B $B%P!<%P%i!V;d$?$A$O$"$J$?$r$:$C$H8+<i$C$F$-$?$o!D(B $B!!!!!!!!!!@$3&$N1?L?$O$"$J$?$N(BScheme$B=hM}7O$K$+$+$C$F$$$k$N$h!"Aa$/!*!W(B $B!JB3$1$k!)!K(B
うお、失敗 (そのとき突如現れた黒い車) (黒服、黒眼鏡の男たちがわらわらと2人を取り囲む) 男「そのディスクを渡してもらおうか」 女「お前は…エルショフ!」 男「久しぶりだな、バーバラ・リスコフ」 女「逃げるのよ、早く!」 学生「え…?」 (強引に学生の手を引いて走り出すバーバラ) エルショフ「待て!ええい、追え!」 (銃を引き抜いて追いはじめる男たち) 「ダーン!」 バーバラ「う…」 学生「あ!」 バーバラ「…私のことは良いから、逃げなさい! そのディスクを持って、横田基地のアタナソフ大佐の所へ…」 学生「で、でも…」 バーバラ「早く、英一君!」 鉄男「どうして僕の名を?」 バーバラ「私たちはあなたをずっと見守ってきたわ… 世界の運命はあなたのScheme処理系にかかっているのよ、早く!」 (続ける?)
もういいや(w
463 :
デフォルトの名無しさん :01/10/30 00:32
これ、始めは奇妙に思った (define x (let ((y 0)) (lambda()(set! y (+ y 1)) y))) (x)=>1 (x)=>2
464 :
デフォルトの名無しさん :01/10/30 00:39
>>463 これが環境っていうやつですね。
これみてようやく理解できましたw
465 :
ニセ関西人 :01/10/30 00:59
自分的には端的に下のでもええと思うんやけど、その補助パラの意味はなんやろ?
>>438 (defun triangle_area (a b c)
(let ((s (/ (+ a b c) 2.0)))
(sqrt (* s (- s a) (- s b) (- s c)))))
↓これはヒドイ(藁
(defun triangle_area (a b c)
(labels ((s (x y z) (/ (+ x y z) 2.0)))
(sqrt (* (s a b c) (- (s a b c) a) (- (s a b c) b) (- (s a b c) c)))))
ところでクロージャ云々で、もめてたようやが、なんやそれ?
そんな言葉があったのすら知らんわ。思わず、モノの本を見返してしもうたわ(泣
本郷さんのカリキュラム、HPで見たで。イイ意味でバチモン言語から入るそうで、
このスレ、いわゆる「純粋主義者」が多いわけやな。「PGは動きさえすれば、ええ」って
感覚でしかやってこなかったさかい、ワテみたいな低偏差値の文系独学厨房は、
そーゆー世界、うらやましくて、うらやましくて、あかんわ。ほんま、お手柔らかに。
MCLでMacOSのX用(←こんな名前の新OS)のアプリケ作れるん?古いOSでなく。
細かい定義の話や実装はどうでもいいからさ、 Lisp/Schemeで動くおもろいアプリケーションなんかないの?
467 :
デフォルトの名無しさん :01/10/30 01:32
Lisp/Scheme自体がおもろいアプリケーションです。
468 :
デフォルトの名無しさん :01/10/30 13:12
>>458 なんか勘違いしてると
いけないから一応忠告しとくけど
SFだからな(笑
>>466 >> 細かい定義の話や実装はどうでもいいからさ、
本当にどうでもいいのかと小一時間問い詰めたい。
お前はただ煽りたいだけちゃうんかと。
>>470 煽るつもりじゃなく、本当にどうでもいい。
オレは言語屋じゃないんで、言語はプラットフォームだと思ってる。
だから「その言語をつかって何をつくるか」に興味がある。
まあ数十行程度のサンプル動かして満足してるだけの人が
大半なら用はないです。サヨナラ。
さよなら
473 :
デフォルトの名無しさん :01/10/30 16:49
>>471 言語屋でも、言語はプラットフォームって思ってる人も多いと思うよ。
だけど、それと「その言語を使って何を作るか」に興味があるのは別じゃない?
実際、どの言語を使っても何でも作れるわけだし、
ここにいる人の大半はきっとlispやschemeで何かを作ってない。
「C言語を使ってlisp/scheme処理系を作ってる」と思われる。
>>473 俺はelispは良く使ってるぞ。
公開する程の物じゃないのが多いが、自作Wikiもどきとか、
日記自動整形系スクリプトとか、計算してその結果を
latexのテーブルにするのとか、そういう小物。
このスレッドの
>>2 に目も通さない466は一体何屋さんなのでしょう?
あとでelizaに聞いてみよう。
476 :
デフォルトの名無しさん :01/10/30 22:04
「途中で」(フランス語)
478 :
デフォルトの名無しさん :01/10/30 22:20
おおっ、ありがとうございます。 フランス語だったんですね。
てか、辞書引けよ。
>>476 米国人が英語文章の中で使うような仏語やラテン語は
英和辞典に載ってるよ。Web辞書でも引ける。
481 :
デフォルトの名無しさん :01/10/30 22:37
Babylon で調べて出てこなかったので、あきらめてしまいました。 TR-7500で引いたらでてきました。 すいませんでした。
482 :
デフォルトの名無しさん :01/10/30 22:45
最近schemeで記述してから、Cとか他の言語にトランスレート するってサイクルが多くなってきた。 いいかげんに考えながら作っていくのに向いてるよ。
>>482 Scheme2C? Gambit-C? それとも stalin ?
>>484 いや、Cへのトランスレートには何を使ってるのかなと。
あーあ、さげさげ
>>280 こそウザイ。逝ってよし。
自作にきまってんだろ>485
488 :
デフォルトの名無しさん :01/10/30 23:37
LISPでCOMとかOLEにアクセスできないですか?
VBのかわりにならないかなと思ったので。
とりあえずExcelシートが操作できれば文句無いです。
偏見混じってるが、ガイジンの作ったソースは汚い。>491 実際簡単に作れる。scheme->bytecode->Cだけど。 ここで公開はしない。
>>488 商用のLISPなら、
多分それぐらいのインターフェースは用意されてると思う。
494 :
デフォルトの名無しさん :01/10/31 00:05
>>488 PerlやRubyにCOMインターフェイスのライブラリがあるから、
そいつをGuileなんかに移植してやればOKでは?
あ、kawaを使えばもっといいかも。
kawa(Scheme)->Java->COM
って感じ?
だれか移植して! (つっても処理系どうすんだ・・)
LISP/Schemeでエクセル操作したいょ
したいにゅ
>>488 商用LISPのトライアル版を使ってみるという手もある。
COM関係の移植ってどの程度大変かな?
500 :
もしかして500 :01/10/31 00:26
Variant辺りの実装なんじゃない?>499
501 :
デフォルトの名無しさん :01/10/31 00:32
PerlのをRubyに移植した人のサイトに開発日誌みたいなのが あった気がする。
とりあえずRubyのwin32oleを落としてみた。 ソースは暇が出来たら読むかも。 まあたぶん読まないけど。
503 :
デフォルトの名無しさん :01/10/31 00:36
おれも正直読みたくない。 これは汚れ仕事な気がする。
ありゃ?なんか2633行しか無いよ? 余裕そうに見えるが。 本当にやってる人いないの?
505 :
デフォルトの名無しさん :01/10/31 00:39
逆の発想で、VBでLISPを作るとか。
506 :
デフォルトの名無しさん :01/10/31 00:43
>>504 そうなのか・・。
たしかにエクセルの為だけでも移植するのも悪くなさそうだね。
DLLにして、LISPのオブジェクト渡すインタフェースをかませば
処理系毎で共有化できないだろうか。
508 :
デフォルトの名無しさん :01/10/31 00:59
>>507 カナーリ賛成なんだけど問題はライセンスか。
とりあえず2ch共有って事でいいかな?
最低限、DLL-I/FやFFIを持ってる処理系でないと意味が無い。
インターフェースは、アクセス性を求めるならやっぱり
リストベースがよろしいかと。
配置が重要なデータにはアクセス時にイメージ変換してその都度
同期を取る方式でいけると思うんだけど。
(最初はある程度、効率度外視して、最低限モノを作ってしまうのが良策。)
>>508 ふむ、俺は厨なので良くわからんが、そんな感じか。
とりあえず、unionに新しい型追加して、マーク関数を
テーブルに追加する程度で新しいオブジェクトが追加
できるような処理系でソース公開されててヘボく無い
奴、無い?
俺的にはGC回収時にOleUninitialize()する、
みたいな感じがいいと思うのだが。
でもそれだとdll化とかは無理か。
スタートはとりあえず
(require 'win32ole)
って感じか?
510 :
デフォルトの名無しさん :01/10/31 01:20
こんなのは? (call-with-ole-class "Excel.Application" (lambda (excel) (let ((book1 (excel "Workbooks" "book1"))) (display (get-property book1 "title")) ...))) call-with-ole-classを抜けると、自動的にOLEはcleanupされる。 (set-ole-event-handler excel "SheetSellectionChange" (lambda args ...)) なんてのもいるかな...
512 :
デフォルトの名無しさん :01/10/31 01:39
>>511 その通り、with〜系でやるのがいいと思う。
(gc回収時にやるのは危険かも)
例外処理などは処理系毎に任せるしかないかな。
*ERROR-HOOK*やunwind-protect/脱出系call/ccなど
の機構を使って各自で処理する。
513 :
デフォルトの名無しさん :01/10/31 01:40
(define excel (ole:create-object "Excel.Application")) (define book (excel 'Workbooks "book1")) もしくは、 (define book (excel 'invoke "Workbooks" "book1")) こーいうのがいいな
open,closeとunwind-protectがあれば 安全なcall-withは各自で作れるよ (define (call-with-io name proc open close) (let ((h (open name))) (and h (unwind-protect (lambda () (proc h)) (lambda () (close h)))))) (define (call-with-ole name proc) (call-with-io name proc ole-object-create ole-object-destroy)) (call-with-ole "Excel.Application" (lambda (h) ... )) ※ここでのunwind-protect書式 (unwind-protect try-proc finally-proc)
おや、レスがついてるよ。どうも。
>>473 > 実際、どの言語を使っても何でも作れるわけだし、
これを言ったらおしまいでしょ。
それぞれの言語に向き不向きがあるから言語の研究をする余地があるんだし。
関数型言語の利点をうまく引きだせるアプリケーションというのは
それなりにある。オレが知っている例だと、Lisp 系の言語はある種の
タスク(というかアルゴリズム)を実装するときに非常に重宝する。
具体的には言わないでおくけど、同じことを Perl や Java でやろうとすると
かなり苦労するはずだ。こういう例は他にもあると思う。
>>467-468 のように「Lisp 自体がおもしろい」とかいってるようなのは、
Lisp を大して使いこなせてない証拠だと思う。まあ実装屋さんとしては
それでいいのかもしれないけど、その先へ行ってみてもいいと思う。
>>474 のようなお手軽なバッチ処理程度のことをやっても、
Lisp のありがたみはあまりわからないような気がする。
カッコがついてるだけで満足できるならそれでいいんだろうが、
これまたもったいないと思う。余計なお世話だろうが。
>>475 は Eliza がおもしろい Lisp アプリケーションのひとつだと
思ってるらしいが、あんなのはたまたま最初に Lisp で実装されただけ。
アイデア自体はおもしろいが、今だったら Perl のほうが簡単に
作れるようなものだし、エレガントさでは Prolog版Eliza のほうが上だ。
> ここにいる人の大半はきっとlispやschemeで何かを作ってない。
> 「C言語を使ってlisp/scheme処理系を作ってる」と思われる。
まあそんな感じでしょう。
速くて便利な処理系を目指して頑張ってください。
ありがたく使わせていただきますので。
>>514 unwind-protectってSchemeにもあるの?
r5rsの索引には無さげだけど。
とりあえず
(open-ole "Excel.Application")
みたいなのと511みたいなの、どっちがいいのかな?
513みたいなのはなんとなくSchemeっぽく無い気が
するんだが。継続とか使われると後始末が面倒そう
だけど、そうでも無い?>識者
あ、ちなみに俺は511に一票。
518 :
デフォルトの名無しさん :01/10/31 09:42
>>516 r5rsにdynamic-windっていうのがあるよ。
unwind-protectと違って、前にも後ろにも処理が指定できる。
ついでにRubyのwin32oleで実装されてるクラスのメソッド等 もコピペしとく。 cWIN32OLE=rb_define_class("WIN32OLE",rb_cObject); rb_define_singleton_method(cWIN32OLE,"new",fole_s_new,-1); rb_define_singleton_method(cWIN32OLE,"connect",fole_s_connect,-1); rb_define_singleton_method(cWIN32OLE,"const_load",fole_s_const_load,-1); rb_define_singleton_method(cWIN32OLE,"ole_free",fole_s_free,1); rb_define_singleton_method(cWIN32OLE,"ole_reference_count",fole_s_reference_count,1); rb_define_method(cWIN32OLE,"invoke",fole_invoke,-1); rb_define_method(cWIN32OLE,"[]",fole_propertyget,1); rb_define_method(cWIN32OLE,"_invoke",fole_invoke2,3); /*supportpropputmethodthattakesanargument*/ rb_define_method(cWIN32OLE,"[]=",fole_setproperty,-1); rb_define_method(cWIN32OLE,"each",fole_each,0); rb_define_method(cWIN32OLE,"method_missing",fole_missing,-1); /*supportsetpropertymethodmuchlikePerl;-)*/ rb_define_method(cWIN32OLE,"setproperty",fole_setproperty,-1); rb_define_method(cWIN32OLE,"ole_methods",fole_methods,-1); rb_define_method(cWIN32OLE,"ole_get_methods",fole_get_methods,-1); rb_define_method(cWIN32OLE,"ole_put_methods",fole_put_methods,-1); rb_define_method(cWIN32OLE,"ole_func_methods",fole_func_methods,-1); rb_define_method(cWIN32OLE,"ole_method",ole_method_help,1); rb_define_method(cWIN32OLE,"ole_method_help",ole_method_help,1); rb_define_method(cWIN32OLE,"ole_obj_help",ole_obj_help,0); rb_define_const(cWIN32OLE,"VERSION",rb_str_new2(WIN32OLE_VERSION)); rb_define_const(cWIN32OLE,"APPEND_NONE",INT2FIX(APPEND_NONE)); rb_define_const(cWIN32OLE,"APPEND_EQUAL",INT2FIX(APPEND_EQUAL)); rb_define_const(cWIN32OLE,"APPEND_BRACKET",INT2FIX(APPEND_BRACKET)); rb_define_const(cWIN32OLE,"APPEND_ALL",INT2FIX(APPEND_EQUAL|APPEND_BRACKET)); rb_define_const(cWIN32OLE,"ARGV",rb_ary_new());
mWIN32OLE_VARIANT=rb_define_module_under(cWIN32OLE,"VARIANT");
rb_define_const(mWIN32OLE_VARIANT,"VT_I2",INT2FIX(VT_I2));
rb_define_const(mWIN32OLE_VARIANT,"VT_I4",INT2FIX(VT_I4));
rb_define_const(mWIN32OLE_VARIANT,"VT_R4",INT2FIX(VT_R4));
rb_define_const(mWIN32OLE_VARIANT,"VT_R8",INT2FIX(VT_R8));
rb_define_const(mWIN32OLE_VARIANT,"VT_CY",INT2FIX(VT_CY));
rb_define_const(mWIN32OLE_VARIANT,"VT_DATE",INT2FIX(VT_DATE));
rb_define_const(mWIN32OLE_VARIANT,"VT_BSTR",INT2FIX(VT_BSTR));
rb_define_const(mWIN32OLE_VARIANT,"VT_DISPATCH",INT2FIX(VT_DISPATCH));
rb_define_const(mWIN32OLE_VARIANT,"VT_ERROR",INT2FIX(VT_ERROR));
rb_define_const(mWIN32OLE_VARIANT,"VT_BOOL",INT2FIX(VT_BOOL));
rb_define_const(mWIN32OLE_VARIANT,"VT_VARIANT",INT2FIX(VT_VARIANT));
rb_define_const(mWIN32OLE_VARIANT,"VT_UNKNOWN",INT2FIX(VT_UNKNOWN));
rb_define_const(mWIN32OLE_VARIANT,"VT_I1",INT2FIX(VT_I1));
rb_define_const(mWIN32OLE_VARIANT,"VT_UI1",INT2FIX(VT_UI1));
rb_define_const(mWIN32OLE_VARIANT,"VT_UI2",INT2FIX(VT_UI2));
rb_define_const(mWIN32OLE_VARIANT,"VT_UI4",INT2FIX(VT_UI4));
rb_define_const(mWIN32OLE_VARIANT,"VT_INT",INT2FIX(VT_INT));
rb_define_const(mWIN32OLE_VARIANT,"VT_UINT",INT2FIX(VT_UINT));
rb_define_const(mWIN32OLE_VARIANT,"VT_ARRAY",INT2FIX(VT_ARRAY));
rb_define_const(mWIN32OLE_VARIANT,"VT_BYREF",INT2FIX(VT_BYREF));
cWIN32OLE_EVENT=rb_define_class("WIN32OLE_EVENT",rb_cObject);
rb_define_singleton_method(cWIN32OLE_EVENT,"new",fev_s_new,-1);
rb_define_singleton_method(cWIN32OLE_EVENT,"message_loop",fev_s_msg_loop,0);
rb_define_method(cWIN32OLE_EVENT,"on_event",fev_on_event,-1);
eWIN32OLE_RUNTIME_ERROR=rb_define_class("WIN32OLERuntimeError",rb_eRuntimeError);
続き。
>>518 お、本当だ。ありがと。
522 :
デフォルトの名無しさん :01/10/31 21:28
検索したらDrSchemeとSIODって処理系が出てきた>COM
523 :
デフォルトの名無しさん :01/11/01 00:17
524 :
デフォルトの名無しさん :01/11/01 12:47
>>524 ありがと。ちらっと見たらのってた。
週末にでもちゃんと見てみるよ。
HotDogってソース公開されてないのでしょうか? ダウンロードしたものにはilのファイルしかついて なかいんだけど、、、 仕方ないので.NETに付いてたLispコンパイラのサンプルを いじくってます。
527 :
デフォルトの名無しさん :01/11/01 23:21
>>526 ひょっとして、今月のCマガの.NETSDKサンプルCDの方に入ってます?
529 :
デフォルトの名無しさん :01/11/02 00:29
無いみたいね。 まあScheme->bytecodeな処理系は沢山あるから別にいいか?
530 :
デフォルトの名無しさん :01/11/02 01:20
bytecode化した後で、S式に戻すことは可能ですか?
>>530 一般には無理だね。
最適化しない処理系で、戻すことを最初から考慮して作れば、
かなりな程度戻せると思う。でもマクロとかは無理だろう。
元に戻す事ならできない。 ただし場合によってはS式には直せる。
534 :
デフォルトの名無しさん :01/11/02 10:32
bytecode化したらgcは取っ払えるでしょうか?
535 :
デフォルトの名無しさん :01/11/02 11:31
538 :
デフォルトの名無しさん :01/11/02 14:23
なにも4人掛かりで否定しなくても・・ 同意見でもその理由とか別の切り口で書けば良いじゃん。 つーわけで、リストを生成して返すような処理を bytecode化する場合を考えてみて>534
n次の行列の逆行列、もしくはn元1次連立方程式を Lispで解きたいのですが(実際にはn=6で使う)、 だれかLispで作ったひといませんか?
541 :
デフォルトの名無しさん :01/11/02 17:06
>>539 >>534 実はgcの必要性はbytecodeとは関係なさそうだね。
リストを生成して返すだけならgcなくてもがんばれるかもしれないけど、
リストが互いに参照しあって循環構造になってるときがgcが必要。
もっともメモリを使い尽くしたら実行をあきらめるという方針なら
どんなプログラムでもgcはいらない。
bytecode化によるメモリ面の利点はプログラムを表現するための
S式が必要なくなること。
542 :
デフォルトの名無しさん :01/11/02 19:47
primitiveは別にあるとして、 最小、何命令ぐらいのbytecodeで済むでしょうか。
>>542 最小だとどうだろうね。
アーキテクチャの細かいとこにもよるが。
スタックマシンとして、
加減乗除やcar, cdrや述語も別として...
局所変数ロード、ストア
大域変数ロード、ストア
定数のロード
スタック操作(dup, drop)
call, return
branch
branch-if-nil
あとはクロージャに関する命令がいくつか。
継続に関しても何かいるかも。
まあ20命令もあれば十分だろう。
544 :
デフォルトの名無しさん :01/11/02 23:35
>>542 引数構築用スタック操作2命令 push pop
環境アクセス操作2命令 load / assign
定数読み込み1命令(constant-load)
apply(まんま) / retuen の2命令
条件分岐1命令
make-closure(lambdaそのもの)
以上9つ。実際は末尾再帰対応にするともっと増えるかも
applyとか、単体オペレータとしては機能詰め込みすぎだけど。
環境をどうするかが問題。continuationは・・
545 :
デフォルトの名無しさん :01/11/02 23:36
gc有りならpopはいらんかも
546 :
デフォルトの名無しさん :01/11/03 14:38
547 :
デフォルトの名無しさん :01/11/03 16:43
>>540 scheme でよけりゃ sourceforge にある schematics で LU分解ができたはず。
CL だったら検索かけていくらでも出てくると思うけど。
win32oleのソース呼んでるけど・・ めんどっちいもんだね。
549 :
デフォルトの名無しさん :01/11/03 21:03
S式の状態での最適化と、 bytecodeにしてからの最適化は、どっちが効率良いですか?
>>548 めんどっちいね。
俺もちょっと読んだ。
序盤の時間関係とかは全部無視して良さげだな〜、
とか思って読んでって、ole_val2variantあたり
で挫折。結構きついね。
551 :
デフォルトの名無しさん :01/11/03 23:24
>>549 効率の意味がわからんけど、
S式をオプティマイズするコードをS式で書けば
色んなlisp処理系に適用できる可能性がある。
bytecodeだと、その処理系だけにしか適用できない。
処理系の作りによって有効な最適化手段は違ってくると思うけど。
S式の段階で可能な範囲の最適化ですぐに思い付くのは、
・定数の畳み込み
・論理式の単純化
・インライン展開
・一時変数の除去
552 :
デフォルトの名無しさん :01/11/03 23:57
定数の畳み込みは簡単。 ・定数シンボルを含む、定数しか使われていない部分式を見つける。 ・evalる ・該当部分をすげ替える。 これだけ。 定数シンボルっていうのは恒久的に値が変わらない事が保証された 変数シンボルの事。
553 :
デフォルトの名無しさん :01/11/04 00:08
プログラミングの勉強をはじめようと思っているんですが、 CとLisp、どっちから先にはじめたらよろしいでしょうか? ちなみに使用してるのはMacOSXで、書籍ではLispは「リスト遊び」、 Cは結城先生の「C言語プログラミングレッスン」と 「はじめてのC」と高橋先生の「やさしいC」があります。
c
>>553 環境が両方あるんなら、同時にやるって考えは無いの?
最初にCやって、リストや木のデータ構造がどんなものか把握できたら
LISPもやってみるとか。
結局は目標とか、何か作るつもりでもないと上達しない気がするけど。
>>555 どう読むと,環境が両方あると読めるのか解説してくれ.
>>556 Macつってるから、仮定のつもりだったんだけど。
Macの開発環境なんて知らないし。
558 :
デフォルトの名無しさん :01/11/04 01:07
lisp
559 :
デフォルトの名無しさん :01/11/05 00:00
(define f (let((a 1)) (lambda(b) (+ b a)))) (define g (f 1)) こういうのをbytecodeに直すとなるとどうなるんですか?
560 :
デフォルトの名無しさん :01/11/05 00:07
間違えました。こういうのです。 (define f (let((a 1)) (lambda(b) (lambda ()(+ b a))))) (define g (f 1)) (g) => 2 gはfで作られる環境を参照してるから、gだけをコンパイルしたら 矛盾しますよね? 環境の共有を維持したままbytecode化ってできるのかな?
561 :
デフォルトの名無しさん :01/11/05 00:36
>>560 bytecode化以前にその定義ではgは関数じゃなくて変数で値は2ですよ。
コードは存在してないです。
562 :
デフォルトの名無しさん :01/11/05 00:44
>>561 (f 1)でclosureが返されてる風に見えるが?
563 :
デフォルトの名無しさん :01/11/05 00:55
で、 (compile g) とかする時に、gの環境も渡せばいい gの擬似コード(適当 pushenv g-env ;gの環境を渡す pusharg a ;<=g-envに存在 pusharg b ;<=g-envに存在 pusharg + ;operator apply return でもこれをファイルなどに保存する時に問題になる。 バイトコード化してもfから生成させないと成り立たない。
なるほど。 どのみち関数の環境を取ってくる必要ありと。 f側で変更の恐れがなかったら、そのまま (define g (let ((a 1)(b 1))(lambda () (+ a b)))) と見なしちゃってもいいですね。 この場合結局、 (lambda () 2) ですけど。
565 :
login:Penguin :01/11/05 07:55
中間コード方式のScheme処理系で一番有名なのって何ですか?教えて下さい。
566 :
デフォルトの名無しさん :01/11/05 11:16
>>565 Scheme48
MIT-Scheme
567 :
デフォルトの名無しさん :01/11/05 13:04
569 :
デフォルトの名無しさん :01/11/06 01:44
MITScheme使いはじめたものですが、MIT Schemeで 補完を使う方法は無いのですか? あと、実行したコマンドの履歴って使えないでしょうか? そういうことやるのはEdWinの方なんでしょうか?
570 :
デフォルトの名無しさん :01/11/06 08:51
EdWin使ったこと無いけど、GNU Emacsなら Inferior Scheme mode で補完できるよ。
コンパイルできるscheme処理系ってどんなのがありますか?
572 :
デフォルトの名無しさん :01/11/06 12:57
>>571 (eq 'コンパイルできるscheme処理系
(or bytecodeベースの処理系 Cトランスレータのある処理系))
573 :
デフォルトの名無しさん :01/11/06 12:58
Cトランスレータとは限らないか
>>571 Hotdogにするのもいいかも。
IL覚えられて一石二鳥。
575 :
デフォルトの名無しさん :01/11/06 16:02
>>571 chez.
インタプリタが入力するたびにインクリメンタルにコンパイルします。
ただし商用。
576 :
デフォルトの名無しさん :01/11/06 21:57
>>568 funarg problemって、静的スコープのschemeでも関係あるの?
577 :
デフォルトの名無しさん :01/11/06 22:21
>>575 インクリメンタルって、
read-evalの間にcompileかませば、同じ事にならない?
read-compile-eval-loop
578 :
デフォルトの名無しさん :01/11/06 22:25
579 :
デフォルトの名無しさん :01/11/06 22:59
東工大の2年生が混ざってそう 今年から、「フォトショップみたいなのを作ろう」 になったんだっけ? 去年までは、自然言語解析プログラムだったけど あまりに難しいという事で、課題が変わったらしい でも、たった5,6回の授業でschemeやって 残りの5,6回でprologってのもね もっとゆっくりやればいいと思うけど
なんかやたら分厚い本出てたね。 GUIもできますみたいなやつ。
>>578 合成型ならタグ付けたりするかも。
それとassertは実行時に評価するわけだから、
scheme側で補足してもいいのでは?
マクロでassert作っておけば不要時にnop変換もできるでしょ。
(define assert-debug #t)
(define-macro (assert test)
(if assert-debug
`(if (not ,test) (error "assert:" ,test))
#t)) ;nop
(define (div s n)
(assert (and (number? s) (number? n) (positive? n)))
(/ s n))
cygwin で gcl か guile コンパイルできる?
583 :
デフォルトの名無しさん :01/11/07 12:26
584 :
デフォルトの名無しさん :01/11/07 12:49
>>582 guile なら Project HeavyMoon にバイナリがあるよ.
585 :
デフォルトの名無しさん :01/11/07 21:27
普通、インタプリタからバイトコードにコンパイルしたら、 何倍ぐらい速くなるものですか?
実装による
587 :
デフォルトの名無しさん :01/11/07 21:40
>>586 ええと、普通は、どれぐらい速くなる事期待して作るんですか?
バイトコードの形式にもよるんじゃないに?
>>587 普通って何?
標準の速度というものが存在しない以上、計測不能だけど。
590 :
デフォルトの名無しさん :01/11/07 22:15
>>589 じゃあ主観でかまいません。
バイトコード化したコードの速度を1として、
インタプリタとの比がどれぐらいひらけば満足しますか?
なんでJavaってPerlより遅いのか?w
592 :
デフォルトの名無しさん :01/11/07 22:37
593 :
デフォルトの名無しさん :01/11/07 22:44
大雑把な目安として、 bytecodeは3倍。 ネイティブは10倍。
594 :
デフォルトの名無しさん :01/11/07 22:45
lispはそれなりに実装すればインタプリタのまんまでも そこそこ速いんじゃない?bytecodeは所詮駆動ループだから、 nativeにはかなわない。 正直、bytecodeって、eval通すか通さないかぐらいの違いしか 無いんでは? コンパイラが項書き換えの様な最適化を施さない限りは。 つーわけで憶測でしかないが、せいぜい2倍ぐらい速くなれば 良い方だと思うけど、どう?
595 :
デフォルトの名無しさん :01/11/07 23:17
Scheme で、 log23 (底が2で真数が3のロガリズム) を計算するには、どうすればいいの? 底が10の常用対数なら log x って素直にやればいいというのは直感でわかるんですが。
(/ (log 3) (log 2))
597 :
デフォルトの名無しさん :01/11/08 00:11
>>596 すげぇ。
そうやればよかったんだ。
ありがとう。
599 :
デフォルトの名無しさん :01/11/08 09:11
>>599 バイトコンパイルを前提としてるんだからインタプリタは速度を重視してないのでは?
普通インタプリタっていってもマクロの展開とかはあらかじめ済ませておくよ。
ただ、0.7秒は速いね。優秀なコンパイラだと思うよ。
インタプリタの52秒はどう考えても遅すぎ。
P5 166MHzなら5秒程度が妥当じゃないのかな。
602 :
デフォルトの名無しさん :01/11/08 19:20
DrScheme(MzScheme?)とMIT Schemeではオブジェクト指向の 実装の仕方が違いますよね? どちらかを使いたいのですが、どちらが優れているのですか? それぞれの特色みたいなのはありますか?
603 :
デフォルトの名無しさん :01/11/08 20:35
604 :
デフォルトの名無しさん :01/11/08 20:42
605 :
デフォルトの名無しさん :01/11/08 23:45
MIT-Schemeは遅い、って事ぐらいしか知らない。
>>603 違うみたいですよ。マニュアル見比べたら、定義の仕方が
全然違ってました。
>>604 素晴らしいページですね。こんな記述がありました。
> Some Schemes have their own built-in OO system.
> Most of these (e.g. in Bigloo, MIT Scheme, OpenScheme, STklos) are
> similiar to the Common Lisp Object System (CLOS), while others
> (e.g. in PLT Scheme, RScheme) are conceptually closer to C++ and Java.
> Kawa is fully integrated with the Java object system, i.e. it allows Java
> classes to be defined and extended in Scheme.
つまり、MITSchemeはCLOSに近く、DrSchemeはC++やJavaに近いようです。
>>605 そうなんですか?CLOSに近い方が柔軟性ありそうな気がして私には魅力的なんですが。
ハンニバルで自分の脳みそ食ってたやつがいたけど, これは recursion ですか?
脳細胞は細胞分裂しないので再帰ではありません。
それは単なる自傷行為
610 :
デフォルトの名無しさん :01/11/09 22:23
>>606 遅いって言うのは、他の処理系がprimitiveとして実装しそうな処理も
全て仮想マシン上でやってるからだろう。
(でも昔Yale大で作られたT-Schemeという処理系も同じ様な思想だったけど、
あっちは速かったという話)
611 :
デフォルトの名無しさん :01/11/09 22:27
単純に速さを求めるならBiglooという処理系がある。>610
>>608 脳細胞が細胞分裂したら無限再帰で帰ってこれないと思われ。
つーか食っても食ってもふやけて減らない大盛マーボ春雨を思い出した
速さと言えばStalinは?
615 :
デフォルトの名無しさん :01/11/10 00:32
ここって、LispとScheme両方語っていいところなのですか?
616 :
デフォルトの名無しさん :01/11/10 01:03
617 :
デフォルトの名無しさん :01/11/10 02:01
LISP, SCHEME の実装っていくつぐらいあるのですか? 有名なやつだけでもいくつもありますよね。 LISP or SCHEME を始めてみたいのですが、お勧めの処理系はありますか? プラットフォーム不問で、テキスト処理、簡単な数値計算がしたいです。 GUI が作成できれば尚良いのですが、そういう方面には向いてないでしょうか。 Perl, Perl/Tk の代わりにしたいのですが。 オブジェクト指向だということで、CLOS にしてみようかと考えているのですが、 いかがでしょう? 識者の皆さんのご意見をお待ちしております。
>>617 Lispの実装の数はプログラミング言語の中で最大かと。
Guileが617さんのニーズにはあってるような気がする。
619 :
デフォルトの名無しさん :01/11/10 02:43
>>618 どうもありがとうございます。
Guile というのは聞いたことがあります。
SCHEME のインタープリタに GUI ライブラリ ( Gtk? ) がバンドルされている
というイメージで良いのでしょうか?
621 :
デフォルトの名無しさん :01/11/10 02:51
LISPでSQLのサーバーとか、MTA、HTTP サーバーって作れますか?
作れないわけないだろ
ありがとうございます。TCPIPとか 同期オブジェクトは使えるんですね。 とりあえず、簡単なMTAでも作ってみ ます。
HTTPサーバならあった様な
625 :
デフォルトの名無しさん :01/11/10 09:16
626 :
デフォルトの名無しさん :01/11/10 11:49
リスプはじめました
627 :
デフォルトの名無しさん :01/11/10 12:38
ヒィー(((゚Д゚)))ガタガタ (de(゚Д゚)(lam()(lam()'ガタガタ))) (((゚Д゚))) ==>ガタガタ
629 :
デフォルトの名無しさん :01/11/10 14:11
stalinが使えるのは何?linuxだけ? ドキュメントが何にもなくて、ただ置いてあるだけなんで、 どうにも分かりません。
630 :
デフォルトの名無しさん :01/11/10 14:45
>>627 (de(゚Д゚)(lam()(display 'ガタガタ)(゚Д゚)))
((゚Д゚))
ガタガタ
(((゚Д゚)))
ガタガタガタガタ
((((゚Д゚))))
ガタガタガタガタガタガタ
631 :
デフォルトの名無しさん :01/11/10 16:43
検索しろよ
632 :
デフォルトの名無しさん :01/11/10 17:00
自作schemeで計算に消費されるconsとnumberを数えてみました。 (define (fib n) (cond ((= n 0) 0) ((= n 1) 1) (else (+ (fib (- n 1)) (fib (- n 2)) )))) (fib 10)=>55 コンパイル前 cell 13471 num 2784 コンパイル後 cell 5704 num 1032 (fib 25)=>75025 コンパイル前 cons 18495431 num 3820480 コンパイル後 cons 7808734 num 1410346 この無駄なオブジェクトの量産を抑止したいんだけど、 どんな手がありますか?
633 :
デフォルトの名無しさん :01/11/10 18:03
sicp 買った. いい本だね. このスレの人々は自分で lisp 実装したりしてすげえと思っていたが, この本を読んですごさが少し減少されました.
634 :
デフォルトの名無しさん :01/11/10 18:40
635 :
デフォルトの名無しさん :01/11/10 18:56
計算機プログラムの構造と解釈
636 :
デフォルトの名無しさん :01/11/10 19:42
>>635 ふむ。紀伊国屋にあるみたいだから読んでみます。
情報サンキュ。
637 :
デフォルトの名無しさん :01/11/10 19:51
図書館いけよ
638 :
デフォルトの名無しさん :01/11/10 19:52
Schemeやるんならこの本もとカタログに書いてあったよその本(計算機プログラムの構造と解釈 )
639 :
デフォルトの名無しさん :01/11/10 19:53
くどい様だけど、原著の英語版はweb上で読めるよ>636
640 :
デフォルトの名無しさん :01/11/10 19:59
さらに言うと、sicpは継続やマクロといった比較的新しい機能の 使い方は扱ってないので念のため。
641 :
デフォルトの名無しさん :01/11/10 20:13
>>632 そのfibは元々、大量に資源を消費するやつでしょ。
末尾再帰版で評価し直したら?
643 :
デフォルトの名無しさん :01/11/10 20:55
sicpはビギナーの本ではない。 と言うより、ビギナーの定義が一般人とずれているような気がする。 あれは、2,3の言語(c,pascal系)をそれなりに勉強してからやると、 具体的なイメージのつかめる本だ。 そのビギナーの定義に付いて混乱があるため、 賛否両論多いのではないかと思う。
645 :
デフォルトの名無しさん :01/11/10 23:07
4章は必見だと思う。
646 :
デフォルトの名無しさん :01/11/10 23:18
最適なパターンマッチ関数を動的に作りたいのですが、 良い方法は無いでしょうか。 例えば (match? '(lambda ()) s) ↓これを (and (pair? s) (eq? (car s) 'lambda) (pair? (cdr s)) (null? (cadr s)) (null? (cddr s))) に直したい。
647 :
デフォルトの名無しさん :01/11/10 23:33
その程度だったらequalのログとれば?
648 :
646>647 :01/11/10 23:52
ありがとうございました。良く考えたらなんか簡単でしたね。 でも始点から辿っていくとca..dr参照が長くなって 効率悪くなるなあ・・
>>646 どっかに似たような事してるソースがあった気が
matchとかで検索
650 :
デフォルトの名無しさん :01/11/11 00:11
「計算機プログラムの構造と解釈」はマサチューセッツ工科大学の計算機科学での入門レベルの科目である。これはMITで電気工学か計算機科学を専攻するすべての学生にとり「共通コアカリキュラム」の四半分として必修である。
ほかには回路と線形システムな二科目とディジタルシステム設計な科目がある。われわれは1978年からこの科目の開発に関わってきており、1980年の秋学期からこの教材を現在の形で毎年600名から700名の学生に教えた。
これらの学生のうち、多くは計算機で少しは遊んだことがあり、僅かはプログラムやハードウェア設計の経験をもっているが、大部分は計算の正式教育を少ししか、または全く受けていない。
------------------------
いじょ、「第一版への前文(日本語訳版)」より。
>>644 違うようです……少なくとも、製作者の意図によると。
651 :
デフォルトの名無しさん :01/11/11 01:02
652 :
デフォルトの名無しさん :01/11/11 01:14
>>650 だから、644がいってるのは、その製作者の意図と一般人のビギナーの定義が違う
ということだろ。
そりゃそうさ。MITなんて世界一の大学だからな。
MITにとってのビギナーが一般人にとってのビギナーと同じわけが無い。
>>651 はじめてのプログラミング言語
って、まるっきりこの板の厨房レベルの話題だな
>LispやPrologも当初思われていたような万能なプログラミング言語ではなく、人工知能や自然言語処理などの特定分野で使われるにとどまっている。
せんせーレベルがこれだよ(w 最強の〜とか好きだよね。 信じちゃいけないよ>654
657 :
デフォルトの名無しさん :01/11/11 04:39
同じ本には mit の学生だから理解できるのだとか考えちゃいけないと ありましたが. 確かにあの本の内容全てを理解することはできなくても, 学部生の時にああいうものに触れておくというのは貴重だと思った.
>>651 その文書
MIT では Scheme を教えているが
Scheme は特定分野でしか使われていないから
(MIT での教育が)うまくいっているとはいえない
って感じだね…。
659 :
デフォルトの名無しさん :01/11/11 04:54
CRLはどこの処理系をつかってるのかな? 自前?だったらすごいな。
>>659 Allegro CLかなんかだったと思う。
でも、なんか会社自体の様子があまり芳しくなくなってしまったようで残念。
662 :
デフォルトの名無しさん :01/11/11 19:48
実は仕事でscheme使ってるけど、回りには内緒だ。
MITの威光を過大評価しているのでは? たかだかunder graduateの学生。しかも一年生でしょう。
664 :
デフォルトの名無しさん :01/11/11 23:38
MITはともかく、リストを扱うならlisp系がいい。
666 :
デフォルトの名無しさん :01/11/12 02:07
>>660 その書評で一つ星と五つ星が極端に別れてるのは面白かった.
>>663 でも20歳とかその辺だろ?
一番頭がいい時期じゃんかよ。
それに、百歩譲ってMITがあまり凄くないとしても
平均レベルの人とはやはりレベル差があると思う。
教育の場の雰囲気とか体感したいなあ。 鬱だ・・
大学に入ってからはアメリカの方が厳しいが、 入った時点では日本の大学生の方が優秀だよ。 高校生の成績を見れ。
>>669 だからって、MITが普通レベルということにはならない。
日本の大学生が優秀なわけないだろ>669
>>671 東大に合格した学生とMITに合格した学生だと
前者の方が数学や理科の成績は良いよ。
そんなこと、どうでも良いことでは? 東大と比べてどうだろうが話とはあまり関係ない。
結論. mit だろうが東大だろうがアフォはアフォ.
674は高卒
>>673 もちろんどうでも良い事。
アメリカの大学生だからと逝って崇め奉る必要はないという話。
>>676 だから、関係ないことを突然しゃべって何になるんだ。
話をずらしてるだけ。
MITは普通レベルとは違う。それだけで話の流れとしては十分 だったはず。東大と比べてどうとかいう話は意味が無い。
679 :
デフォルトの名無しさん :01/11/12 04:27
>>677-678 MITが特殊だからできて、他じゃ無理というのが馬
鹿げた議論であることがはっきりすると思うが。
東大はただの例だよ。それくらいいちいち言わせるな。
MIT = 武蔵工業大学
681 :
デフォルトの名無しさん :01/11/12 04:46
>>679 はぁ?全然馬鹿げてない。
MITが特殊だから初心者向けでも一般と食い違いがある。
東大よりMITのレベルが低くてもそれは成り立つ。
どこがおかしいんだよ。言ってみろよ。
schemeを採用してるのは、数時間でだいたい使い方はわかるし、 すぐ実行して試せるからでは? 最初は「文を前置記法にして括弧で括る」って事だけ 覚えればいいから。 (文がリストで出来ているって事は特に意識しない)
683 :
デフォルトの名無しさん :01/11/12 04:52
>>681 「一般」って何だよ?
東大もMITも「一般」じゃないのか?
じゃあ京大や阪大や...や日大や東洋大はどうなんだよ?
SICPがエリートにしかわからん小難しいもののように言うのが
馬鹿げてるって言ってるんだよ。
684 :
デフォルトの名無しさん :01/11/12 05:03
どんな難しい本でも百篇よめば分かる。 だれか有名なひとが言ってたな。 理工系の人じゃないけどw
SICPは、初心者向けでも上級者向けでもある 読者のレベルが上がれば、SICPのレベルも上がる
686 :
デフォルトの名無しさん :01/11/12 05:11
>>685 そう。そうが名著たる所以。
K&Rもそうなのかな?読んだことないけど。
688 :
デフォルトの名無しさん :01/11/12 05:32
>>683 東大もMITも「一般」じゃないね。
平均とは明らかにレベルが違う。
京大も阪大もそうだな。
もっとレベルを落とすと怪しくなってくるかもしれないが、それだって
程度問題だ。
それに、誰もエリートにしかわからんとは言ってないだろ。
SICPに初心者用と書いてあっても、普通の初心者用とはちょっと違うのではない
かという話になってるだけのことだ。
この板で言う一般人は中高生です。
初心者とか一般って良くわかんないけど、 竹内郁雄先生の本でLisp (てゆーか、プログラミング) 入門をした私は逝ってよしですか? SICPは、あとになって実際に使える環境得てからぱらぱら 飛ばし読みして、ふふんって感じでした。こんど、 ちゃんと読み直そうと思います。
偏差値50ぐらいの大学が普通だろ。
693 :
デフォルトの名無しさん :01/11/12 17:22
結論として、SchemeはMIT生や東大生ならともかく、一般人には とても理解できない難解なもの、ということですね。
MITや東大の話をするのはもう止めましょうよ。
申し訳ない。私の
>>651 の発言で話が無用な方に行ってしまった。
これ以上やりたい奴は学歴板に逝ってくれ。
あくまでもあの本はSchemeを学ぶ本ではない(翻訳された和田先生もそう
おっしゃっている)。私は
>>651 のリンクに載っている大学で
Schemeに触れたのだが、計算機科学の教科書としてはSICPは良いと思う。
ただ、計算機のイロハもわからずその他のプログラミング言語の
利用経験もない、計算量の概念も分からないド素人が人の助けもないまま
あの本で勉強するのはちょっと難しいとおもう。多分それだけのことでしょう。
http://www.ipl.t.u-tokyo.ac.jp/sicp/epilog.html でもいま湯浅先生の本って書店に行ってもないんだよね。最近Scheme
の本が新しく出たそうだけどだれか読んだことありますか?
>>696 最近でたSchemeの本なら読んだことあるけど、なかなか
しっかりした普通の本。
ただ、入門書にしてはちょっと難しい。
698 :
デフォルトの名無しさん :01/11/12 20:44
最近でたの?>697
700 :
デフォルトの名無しさん :01/11/12 22:25
村上訳の方かと思った。
日本のscheme本の著者は最低限R*RSを訳せる能力が必要みたいだな。
702 :
デフォルトの名無しさん :01/11/12 23:08
Dybvig本は比較的オーソドックスな "XXX: The Language"スタイルの本だよ.
704 :
デフォルトの名無しさん :01/11/13 22:27
最近出たLispのぶ厚い本(著者日本人。A5サイズ)ちらっと眺めたけど、 結構良い感じだった。Macに偏ってたけど。 LispでGUI作るのも面白そうそうだね。
そうだね(w
706 :
デフォルトの名無しさん :01/11/14 00:18
素朴な疑問なんですけど ISLISP って CLtL2 と比べるとどうなんでしょ? 特に OOP、 CLtL2 ならCLOS 周りとか。
707 :
デフォルトの名無しさん :01/11/14 00:23
708 :
デフォルトの名無しさん :01/11/14 00:30
>>706 どうなんでしょ?と聞かれて何を答えればいいんだ?
>>710 >ところでLispが使える仕事ってないものですかね。
つーか強引に普段の仕事で使ってみれば?
煙たがれる様だったら、こっそり組み込んじゃえ(w
>>710 AIBOに笑えないほど本格的な人工知能を。
>>709 CLtL2 をあんまりわかってないんですけど、 ISLISP と CLtL2 ソースや動作の互換性とか。
CLOS でつくってソース持っていけるのかなと。
713 :
デフォルトの名無しさん :01/11/14 00:54
>>712 ISLISPはCommonLispの下位互換と見なせば根本は多分同じだから、
ISLISP側で足りない物を補完すれば同じ様に動くと思うけど。
>>710 とりあえずlispコアをdllにでもして、
外部から扱える様にしとくと便利。
lisp_handle h = lisp_create();
lisp_evalstring(h, "'(a b c)");
obj = lisp_result(h);
・・・
>>713 いきなり CLtL2 は理解するのが大変なので、 ISLISP ならまだ小さいから覚えやすいかなと。(w
>>714 なるほど、下位互換っていう位置づけだったのか。
全然違う仕様を作ったのかと思ってた。
>>716 そうでしたか。
ついでに。
http://www.okilab.com/islisp/islisp.html >ISLISP の目的は、一貫した言語仕様をもち、産業界での使用に耐え得る品質を持った、
>Common Lisp のサブセットを開発することであり、
……
>仕様の検討が行なわれながら,今回のISLISP規格に含まれなかった
>機能として,パッケージあるいはモジュールがある.
>実用的なソフトウェアの開発では,名前の衝突を解決するこれらの機能は不可欠であり,
>今後の課題である
だそうです。
718 :
デフォルトの名無しさん :01/11/14 01:49
CommonLisp内でソース互換があればいいんじゃない? ISLISPでも動く様にするってのは、趣味でしょ。 変なこと気にしながら中途半端なコードを書くよりは、 CL2ISLISPを作るとかした方が健全。
719 :
デフォルトの名無しさん :01/11/14 12:41
S式を文字列に変換したいんですか、いい方法ないですか。 '(a b (e f) c d) -> "(a b (e f) c d)"
721 :
デフォルトの名無しさん :01/11/14 19:40
>720 できました。ありがとうございます。
722 :
デフォルトの名無しさん :01/11/14 22:18
>>719 schemeならこうかな?
(define (s-expresstion->string s)
(call-with-output-string (lambda(port)(write s port))))
(define (string->s-expresstion s)
(call-with-input-string s (lambda(port)(read port))))
723 :
デフォルトの名無しさん :01/11/15 01:15
SICP の問題がいきなりわからん. 問題 1.5 なんですけど, (ひまがある人は見てね) 正規順序にしても作用順序にしても, (p) を展開したり評価している所で 無限ループに陥るような気がするんですが. 誰か教えて下さい.
Exercise 1.5. Ben Bitdiddle has invented a test to determine whether the interpreter he is faced with is using applicative-order evaluation or normal-order evaluation. He defines the following two procedures: (define (p) (p)) (define (test x y) (if (= x 0) 0 y)) Then he evaluates the expression (test 0 (p)) What behavior will Ben observe with an interpreter that uses applicative-order evaluation? What behavior will he observe with an interpreter that uses normal-order evaluation? Explain your answer. (Assume that the evaluation rule for the special form if is the same whether the interpreter is using normal or applicative order: The predicate expression is evaluated first, and the result determines whether to evaluate the consequent or the alternative expression.)
725 :
デフォルトの名無しさん :01/11/15 01:27
ベン ビットディドゥルは次のようなテストを考えました。彼の手元にあるインタープリターが、applicative-order な順序の評価を実装しているか、または普通の順序の評価を実装しているかを、調べるテストです。 彼は、次のような2つの手続きを定義しました。 (define (p) (p)) (define (test x y) (if (= x 0) 0 y)) そして、彼は次の式を評価しました。 (test 0 (p)) applicative-order なインタープリターでは、どんな結果になるでしょうか? normal-order な評価ではどうなるでしょう? あなたの考えを説明してください。 (normal と applicative とで、スペシャルフォーム if の動きは同じものとします。 ifの条件式がはじめに評価されます。その後に、その結果が真か偽かによって、then部とelse部がそれぞれ実行されます。)
726 :
デフォルトの名無しさん :01/11/15 01:35
(test 0 (p)) を評価すると (if (= 0 0) 0 (p)) になるから、 (if (TRUE) 0 (p)) ↓ 0
>>724-726 guile で実際にやってみたんですが,
(if (= 0 0)
0
(p))
だと, if は special form なので確かに (p) は評価されないんですが,
(test 0 (p))
だと止まらなくなります.
問題の出し方は applicative-order と normal-order で異なる振るまいをする
という感じなので, どっちかは止まるのかなと思ってるんですが,
applicative(作用) order だと (test 0 (p)) の (p) の評価の時に止まるし,
normal (正規) order だと演算子 (p) の展開が無限に続いて止まらないのでは
と思うのです.
guile は作用順序だと思うので, 正規順序の時実際にどうなるかは
わからないんですが.
728 :
デフォルトの名無しさん :01/11/15 02:20
>>727 normal orderだと726の書いた通り止まる。(p)は評価されないから。
(展開って何?)
Schemeのようにapplicative orderだと止まらない。
729 :
デフォルトの名無しさん :01/11/15 02:23
正規順序: 最も左の書き換え可能な式(redex)を書き換える。 作用順序: 他のredexに含まれていないredexのうち、最も左のものを書き換える。
なーるほど. わかりました. normal order だと (test 0 (p)) の test のみが演算子であって, この時点では (p) は演算子ではないので, (p) が評価されたり 展開されたりするということはないんですね. 展開というのは SICP の日本語版の説明にあった言葉ですが, ここでは被演算子を評価しないで演算子を基本演算子が出てくるまで 置換えていくことを指すようです. もっとも置換えという言葉も, 厳密に定義するとずいぶん難しいということが脚注にありました. やっとわかりました. みなさんどうもありがとうございました.
731 :
デフォルトの名無しさん :01/11/15 08:53
正規順序のscheme作った人いる?
SCIPの問題を順々に解いていくのをここでやるのはイイかも! 俺は第三章まではスムーズに来れたんで、そこまではアドバイスできる。 あの本はどんどん難しくなるんで、仲間がいないとつらいよ。
俺はわかんない奴は速攻ですっ飛ばして、 全部おわらしました。 問題は、そうですねー、7割くらいしか解いてません。
いけないな、それは。 自分で考えないと。
736 :
デフォルトの名無しさん :01/11/15 11:58
>>731 MLに対するLazy-MLみたいなのか。
インタプリタなら難しくないね。Scheme自身で書けば特に簡単。
でも、自分でdelayとforce使えば、素のSchemeでも似たような
ことはできるよ。
・(car, +, <などstrictなprimitive関数を除く)関数呼び出しの引
数はすべて(delay ...)で囲う。
・変数参照は全て(force ...)で囲う。
とするだけ。
(define lazy-tak
(lambda (x y z)
(if (not (< (force y) (force x)))
(force z)
(lazy-tak (delay (lazy-tak (delay (- (force x) 1)) y z))
(delay (lazy-tak (delay (- (force y) 1)) z x))
(delay (lazy-tak (delay (- (force z) 1)) x y))))))
(lazy-tak (delay 18) (delay 12) (delay 6)) => 7
あ、(delay (force x))は最適化してxと書いてある。
kawaは正規順序だった気が。
739 :
デフォルトの名無しさん :01/11/15 13:15
んなわけない>738
正規順序ってのは、 実装用ではなく、 人間の理解に資するための方法ではないのだろうか?
正規順序って要は遅延評価でしょ?
多分違う。
多分だが、遅延評価というのは、 いわゆるcall-by-needと言われる奴で、 正規順序というのは、 call-by-nameとか言われる奴だったと思うが。 自信無いんで適当に調べてくれ。
じゃあ、kawaはcall-by-needだな。
>>744 ちがうって。kawaはただのcall-by-valueだよ。
call-by-nameで生じる無駄な計算を避けるのがcall-by-need。
call-by-name (normal order):
((lambda (x) (+ x x)) (* 10 10))
-> (+ (* 10 10) (* 10 10))
-> (+ 100 (* 10 10))
-> (+ 100 100)
-> 200
call-by-need だと、(* 10 10)をコピーせずに、同じ式を
共有して
((lambda (x) (+ x x)) (* 10 10))
-> (+ (* 10 10) (* 10 10)) ; 2つの(* 10 10)は同一のセルで表す
-> (+ 100 100)
-> 200
みたいになる。
delayとforceを使った場合、forceするたびにdelayの引数を計算
しなおすとcall-by-name。一度forceされたら結果をキャッシュして
計算し直さないのがcall-by-need。(ふつうの実装は後者。)
746 :
デフォルトの名無しさん :01/11/15 17:24
>>740 normal formが存在するならば、正規順序の簡約で必ずnormal form
に到達できるという保証がある。つまり、止まるプログラムなら正
規順序で評価すれば必ず止まる。正規順序で止まらないプログラム
はどうやっても止まらない。
作用順序簡約にはその保証がない。正規順序なら止まるプログラム
も、作用順序だと止まらないかもしれない。そういうプログラムの
例が
>>725 他にも、
(define infinite-list (cons 1 infinite-list))
(caddr infinite-list)
なんていうのは、正規順序の言語なら止まるが、Schemeのような作
用順序の言語では止まらない。
MLやSchemeのような作用順序の言語に比べて、正規順序で評価する
と
>>745 のように無駄な評価が生じて桁違いに遅くなる。そこで
開発されたのがcall-by-need (graph reduction, fully lazy
reduction)。能力は正規順序と同じで、効率が良い。Haskellや
Cleanはfully lazyな言語。
昔、リストのアドレスに対してhash値を適用できないか質問した者です。 あれから、gc直後をフックする様にして、 hash-object毎にrehashする関数をフックに登録する方法で なんとかできました。結果、物凄く速くなりました。 答えてくれた方、ありがとうございました。
かなり昔になんかで勉強したが、 一般に、実引数の評価時期(評価順序)は、3つに分けられるらしい。 1.eager-evaluate 2.lazy-evaluate 3.normal-order んで、1.は、cとかpascalで一般に行われているようなものをいう。 これは、簡単なんだが、不必要な引数(!)まで評価してしまう。 2.は、必要な時に評価されるが、それは最初だけで、 次から同じ物が出てきた時には、どっかに取っておいた最初の評価結果を使う。 3.は、必要な時に評価されるのは同じだが、その評価結果は取っておかないで、 いつもいつも評価する。自明のことだが、これは不効率ということになる。 2.3は関数プログラミングでは、有効とされている方法らしい。今思い出した。 んで、1の不必要な評価って言うのが、例えば、次のような奴。多分。 int f(void){return f(void);} void g(int a, int b){cout << "a has " << a << endl;} ここで、g(1,f());とかやると、終了しなくなる。 これが、正規順序だと、f()は評価されないまま終了できる。 つーことらしい。 しかし、考えてみれば分かるが、C/C++とか使っている限りでは、 こんなプログラミングはしない。 そのことよりも、lazy-evaluationをやることのオーバーヘッドが気になってしまう。 まあしかし、最近はほとんど問題にならないということらしいが詳しいことは知らん。
749 :
デフォルトの名無しさん :01/11/15 23:54
まあ、それにしてもマクロがあるんだし、 実装したところで「何に使うんだ」という疑問は残るな・・
750 :
デフォルトの名無しさん :01/11/16 00:25
SchemeでRDBってできますか?
751 :
デフォルトの名無しさん :01/11/16 01:19
tail recursion みたいなことは普通の lisp でも できると思うんですが, scheme でとりわけ強調されるのは それが一定以上のスペースを使わないことが保証されている からですか?
752 :
デフォルトの名無しさん :01/11/16 01:34
>>749 Lazyな言語だと、なんていうか、式をいつ使うかとか
「これはまだ評価しちゃいけない」とか考えなくて良くて、
なんだか楽なことがある。
(define quick-sort
(lambda (vector)
(letrec ((recur (vector-append (quick-sort left)
(vector pivot)
(quick-sort right)))
(insert (insert-sort vector))
(parts (partition vector))
(left (car parts))
(right (cadr parts))
(pivot (caddr parts)))
(if (< (vector-length vector) threshold)
insert
recur))))
あんまり良い例じゃないかも知れんが…
recurとかinsertとかは、いわばサブルーチンみたいなもんだが、
それを(lambda () )でくくる必要がなくて、単に「使うかも知れない
式」をどんどん部品として挙げていけば良いというか…
分かってもらえるかな。(ちなみに、Haskellだとletとletrecの
区別は無くって、全部letと書く。)
こういう話って、LISP*みたいな場合はどうなってるのでしょう? てゆっか、あの手のマシンで動くその手の処理系って、いまでも 使われているようなのってあるんでしょうか?
>>753 >あの手のマシンで動くその手の処理系
って何?
Connection Machine上で動くCM LispとかLisp*(Lisp starと読む) の事かな?もうそんなマシン残ってないんじゃないかと思うが… まあ、普通のapplicative orderのLispだよ。ただ、data parallelな並列処理をするための、特殊なデータ構造(Xector, Xet, Xapping)が加わってるだけ。
並列に処理したいとこだけ、それなりの書き方で書くってことですか?
何でも並列になるのかと思ってた。解説thx
>>755
757 :
デフォルトの名無しさん :01/11/16 19:47
もうちょっとレベル下げてくれ。
758 :
デフォルトの名無しさん :01/11/16 20:55
data parallelっていうのは、たとえば「配列の要素全部に対して、並列に同じ操作 を実行する」みたいに、データ構造に対する操作として並列処理を行う考え方。 High Performance Fortranとかもそうだね。 CM Lispについては、えーと、うまく説明する自信がないので、詳しくは Connection Machine Lisp: fine-grained parallel symbolic processing , Guy L. Steele and W. Daniel Hillis, Proceedings of the 1986 ACM conference on LISP and functional programming, 1986, ACM Press New York, NY, USA, Pages: 279 - 297, ISBN:0-89791-200-4 を読んで欲しいんだけど、ちょっとやってみる。 xapping (mappingのもじり)とは、写像を表すデータ構造で、 {sky->blue apple->red grass->green} のように書く。順序は関係ない。{grass->green apple->red sky->blue} と書いても全く同じデータを意味する。 (xref '{sky->blue apple->red grass->green} 'apple) => red のように検索ができる。 キーと値が同じ要素(例: apple->apple)は、単にappleと書いて良い。 {apple orange strawberry} のように、そういう要素ばかりからなる xappingをxet (setのもじり)と呼ぶ。 また、[red blue green]は{0->red 1->blue 2->green}と書いたのと同じで、 xector (vectorのもじり)と呼ぶ。 任意のキーに対して同じ値を持つxappingをconstant xappingと呼ぶ。 例えば{->5}は、どんなキーで検索しても値として5が返る。 任意のキーに対してキーと同じ値を返すxappingをuniversal xappingと呼び。 {->}と書く。 任意のキーに対して、キーに1引数関数fを適用した結果を値とするxappingを lazy xappingと呼ぶ。例えば{sqrt}は、任意の数に対してその平方根を値として返 す。 listと同じドット記法で、「その他すべての要素」を表すことができる。 例えば、{pi->1.772453851 e->1.6487212 -1->i . sqrt}とか。
続き。 xappingに対して、αという操作を使って一斉に関数を適用することができる。 mapcarみたいなもの。引数が複数あるとき、複数のxappingでキーが共通の要素 にだけ関数が適用される。 (αcons '{a->1 b->2 c->3 d->4 f->5} '{b->6 d->7 e->8 f->9}) =>{b->(2 . 6) d->(4 . 7) f->(5 . 9)} βは縮約演算。(β+ '{1 2 3 4 5}) => 15 2引数だと、第1引数と第2引数で共通するキーを取り、第1引数の方の値をキー、 第2引数の方の値を値として、関数を適用した結果を返す。例えば、 (β+ '{glass->green sky->blue banana->yellow apple->red tomato->red egg->white} '{grass->1 sky->2 banana->3 apple->4 tomato->5 mango->6}) =>{green->1 blue->2 yellow->3 red->9} red->9は、apple->4とtomato->5の値に関して+を適用した結果。 ヒストグラムは(defun histgram (x) (β+ x '{->1}))と書ける。 (histgram '{a b a a b c d}) => {a->3 b->2 c->1 d->1} この他、Common Lispのsequence関数(remove-ifとかsortとか)はxappingに対しても 使えるよう拡張されている。また、xapping同士の和集合などいくつかの演算が用意 されている。xappingに対する基本操作は全て並列に行われる。 これらを組み合わせて、並列プログラミングができる。APL言語とFP言語の影響を強 くうけている、らしい。
Connection Machine Lispって結局並列計算機上の実装ないよね?
Common Lisp上のemulatorだけで。(まあCM-2に実装できるわけもないが…)
美しいから、100台のPC-UNIXとかで実装したら面白いだろうな。
>>751 最初だから自慢げなんでしょ。
新宿の中村屋のカリーみたいなもん。
>>760 >Connection Machine Lispって結局並列計算機上の実装ないよね?
無いと思う。上の文献はSymbolics 3600上でのエミュレータ。
>美しいから、100台のPC-UNIXとかで実装したら面白いだろうな。
ちょっと粒度が小さすぎるかもね。
こういう場合って「粒度が小さい」って言うんですか? 「粒度」は大きいような気が...ていうか、「粒度が低い」ならわかる。 (いや、揚げ足とるつもりとかじゃなくて、ホントに知りたいのです。)
>>751 いやー、syntax sugarは言語機能から排除して本質的な構文だけにする、
というのがSchemeのポリシーじゃない? tail recursionがloopになる
から、loopが必要ならtail recursionを使えば良い=loopはsyntax sugar
だから実装しない、ということが主張できる。そのためにtail recursion
をどう実装するかを決めておく必要があるってことでしょう。
764 :
デフォルトの名無しさん :01/11/17 16:21
>>765 同意。
唯一の繰返し構文doでさえオプション扱いなのがカコイイ
>>764 同意。
唯一の繰返し構文doでさえオプション扱いなのがカコイイ
766 :
デフォルトの名無しさん :01/11/17 21:35
>>766 無限ループしてるね。stack食い潰しそうだ。
>>762 言葉足らずだった。
「Connection Machine Lispの並列処理機能は粒度が細かいので、PCクラスタ
だと効率が良くないかもしれない」と言いたかった。
粒度というのは並列処理の分割単位の木目の細かさのことで、タスク間の通信
の間にいくつの命令が実行されるかで定義される。Connection Machine Lisp
だとほんの数命令くらいになると思う。
770 :
デフォルトの名無しさん :01/11/18 01:47
SICP訳本4.3章のamb評価器とか、 わかった人いる?
>>769 > 「Connection Machine Lispの並列処理機能は粒度が細かいので、PCクラスタ
> だと効率が良くないかもしれない」と言いたかった。
xappingと同時にα、βを真面目にフル実装しようとすると、
PEは最低でもPalm Pilotくらいの能力が必要だと思う。
集合論的な関数(とその合成を)実装しないといけないので。
> Connection Machine Lispだとほんの数命令くらいになると思う。
となるようにCM Lispを簡略化したのが、CM-2やCM-5で動いていたらしい*Lisp。
C*ってのもあったな。どれも現物使った事ないや。似非エミュ書いた事はあるけど。
772 :
デフォルトの名無しさん :01/11/18 17:20
今TurboLISPとか TurboScheme作れば売れると思うんだけど。>Borland せっかく昔TurboProlog作ったのに
>>772 Delphi/Kylixのようにするとか。
でも、今BorlandがPascalの処理系を作っているのは、TurboPascalの頃からのブランドイメージがあるからだと聞きました。
Lisp/Schemeが今売れるかどうかは別として(売れてほしいなぁ)、Borlandは今のところ他の言語に手を伸ばすつもりはないでしょう。
>Prolog
すごい。
774 :
デフォルトの名無しさん :01/11/19 23:09
lispのクロージャ(自作)関数にも型が欲しいと思わない?
775 :
デフォルトの名無しさん :01/11/19 23:15
>>774 どうだろ。当然primitiveにも、だよね。
Common Lispのequalやsortの型は何?
776 :
デフォルトの名無しさん :01/11/20 00:40
>>775 equalは構造の比較だから置いておくとして、
sortは比較関数次第でしょ?
入出力がリスト->リストだとして、比較関数とリストを引数に取るんなら、
比較関数側の入出力型判定でどういうリストが入力としてふさわしいか
実行前に判るんじゃない?
合成型とかの伝播考えると難しそうだけど。
シンボルをキーとしたalistをソートする場合は、
「caarがシンボルのリスト」とか、最低限何が満たされてる必要があるのか、
でもわかってれば有用なんじゃないかなあ。
777 :
デフォルトの名無しさん :01/11/20 01:53
>>776 sortは文字列やベクタも受け付けるんだけど…
:key, :start, :end引数もあるし…
「caarがシンボルのリスト」って型の概念じゃ表せないと思う。
778 :
デフォルトの名無しさん :01/11/21 20:08
スゲー遅いのをなんとかしたいんだけど、 C言語とタメ張れる様にするにはどうしたらいい? トランスレータ書くしかない?
最適化の奥深い世界へようこそ!
780 :
デフォルトの名無しさん :01/11/21 23:19
>>778 バイトコード化程度じゃ、多分駄目。
制御構造を全部nativeにするとか。
トランスレーターは、同時性が薄れるから個人的には却下。
>778 LISPでCコンパイラ作るぐらいの気合が必要。
四則演算をいちいち関数呼び出ししてたらCに勝てるはずがないが、 インライン展開するためには型が推測できないと。 Common Lispで型宣言つけまくったプログラムなら頑張ればなんとか なるはず…でも大変。
>>782 型が推測以前に四則演算だってただの関数だから
変更されるかも知れないのであらかじめ展開するのは…
EdScheme使ってみたんだけど、いいね。 日本語が通ればもっといいんだけど。
785 :
デフォルトの名無しさん :01/11/22 17:14
786 :
デフォルトの名無しさん :01/11/22 19:36
>>784 ちょっと触わってみたけど、IDEとしてはDrSchemeより良い感じ。
まあ、売り物だし、これぐらいのクオリティは当然かも。
ドキュソ大学生の作った物と比べるのも酷だが。
>>786 DrSchemeはドキュソ大学生が作ったものだったのか?
788 :
デフォルトの名無しさん :01/11/23 01:16
Ctrl+C効くようにして欲しいな。 signalトラップしてそこまでの継続を保存するのって schemeなら簡単だよね?
789 :
デフォルトの名無しさん :01/11/23 01:29
大学生=ドキュソ大学生 ドキュソ大学生=ドキュソドキュソ大学生 すなわち 大学生=ドキュソ
おじさん=ドキュソ
>>789 なんだ、そういうくだらない思考だったのか・・・
わかりにく。(w
792 :
デフォルトの名無しさん :01/11/23 02:29
>>783 Schemeではprimitiveをインライン展開することが規格で許されている。
793 :
デフォルトの名無しさん :01/11/23 16:30
SchemeとLispは違うものと思ったほうがいいみたいだな。 基本的に同じものと思うよりも。
794 :
デフォルトの名無しさん :01/11/23 21:39
インライン展開ってどうやるの? S式解析してまわる場合ってマクロも展開しなきゃいけないの?
795 :
デフォルトの名無しさん :01/11/23 22:08
>>794 インライン展開は簡単、
解析して、展開したい関数名に到達したら、その名前をlambdaに
置き換えるだけ。ただ、これだけでは効率は良くならないから、
不要なlambda/letを削除していく。
この作業が大変。
>>795 そういう話しなのかなぁ?
上の方でprimitiveが〜とかっていってるけど、
primitiveはlambdaを置き換えたりとかしないよね?
>>794 はコンパイルする話をしてる?
>>796 一般的なS式のインライン展開の話でした。
primitiveのインライン展開も興味ありますが、
バイトコードとかの話ですよね?
>>795 やっぱりマクロは展開しないと解析できないですよね?
マクロ毎に解析するロジックを作るのは大変そうだし。
798 :
デフォルトの名無しさん :01/11/24 14:53
Common Lispでもprimitiveをインライン展開する処理系があるよね。 規格的にもOK。(common-lispパッケージの関数は再定義できなくても良い。 再定義しようとするプログラムの動作は未定義。)
>>799 Common Lispでは違う。
standard-objectおよびそのサブクラスだけがいわゆるobject。
しかし、ISLispでも実質的には同じ。整数やconsのサブクラスを作れるわけで
はない。
802 :
デフォルトの名無しさん :01/11/24 18:56
scheme の標準的な拡張パッケージってないんですか? slib? CommonLisp より柔軟なのはわかるけど, 実際に プログラムを作る時はもうちょっと 関数がそろっていた方がいいような気がする.
803 :
デフォルトの名無しさん :01/11/24 20:42
CommonLispエミュる(というほど大袈裟なものではない) パッケージがリボジトリにあった気が。
804 :
デフォルトの名無しさん :01/11/24 20:51
805 :
デフォルトの名無しさん :01/11/24 21:43
SRFIは主に処理系各自で対応する物、 SLIBは初期化ファイルを揃えとけばそのまま使える物。 という感じがする。 処理系にdefine-macro書式のマクロ構文を用意しておくと、 STkやDrSchemeのスクリプト類が使える。 個人的にはS式→S式変換の類(処理系依存しないもの) はもっと広めて欲しい。(SRFI程度では不足)
windows使いがDrSchemeなどでSchemeを覚えると何かいいことありますか? テキストファイルの処理とか。
WindowsのSchemeの処理系って何が一番いいのかな? DrSchemeかな?
808 :
デフォルトの名無しさん :01/11/27 16:00
Guile は正規表現が使えるみたいだけど, 他の scheme で regexp が使えるのありますか.
>>809 お, ありがとうございます.
Gauche って初めて聞いたけど, 見たところ結構よさそう.
>>807 WindowsでSchemeするなら、さしあたってEdSchemeが一番洗練されていると
思う。150ドルするけど、それだけのことはあると思う。もっとも日本語文字化けするけど。
日本語を扱うならKawaがいいんじゃないか。Javaが動作する環境なら、可搬性がある
わけだし。
いやchezschemeだろう、どうみても。
どうせならフリーソフトのほうがいいだろう。
ここのみんなで2ch-scheme作ってよ。 特徴は ・フリーソフト ・さまざまなプラットフォームで動作可能 ・高速なJITコンパイラ搭載 ・日本語などの文字も使用可能 ・その他
815 :
デフォルトの名無しさん :01/11/28 19:41
>>811 EdSchemeってEXE作れるの?
ちなみにSIODって処理系は作れるぞ。
DrかMITで十分。
817 :
デフォルトの名無しさん :01/11/28 22:36
自作が一番いいよ
818 :
デフォルトの名無しさん :01/11/28 22:47
petite chez schemeがインタプリタの中ではおそらく最速だ。 心なしかCPU負荷が高いような気もするが。
819 :
デフォルトの名無しさん :01/11/28 23:37
Petite Chez Scheme って速いね。 EdSchemeのような環境とセットだとすっごくいいと思う。 売り物のChez Schemeはすっごく高価なんでしょ。
821 :
デフォルトの名無しさん :01/11/29 01:09
Lisp/Schme ってやたらとリソースを消費しまくりなイメージがあるんだけど。 特にメモリがすぐなくなるな。 メモリ自体は安くなってるんだけど、ノートだとメモリの最大搭載量が 512MB だったりするので困る。
>>822 処理系 or OS が糞ってことか?
それはそうかもしれないけど、なんかすっきりしないなぁ。
Lisp/Scheme ではそういう問題が起きやすいという印象を持ったよ。
ちなみに WinMe(スマソ) + DrScheme でサンプルプログラムを動かした。
consセルが8バイトだとして、なにかメモリに問題が起きるのか?
825 :
デフォルトの名無しさん :01/11/29 06:08
てゆーか、Guile はなぜ流行らんのか?
826 :
デフォルトの名無しさん :01/11/29 06:15
てゆーか、Ruby はなぜ流行らんのか?
827 :
デフォルトの名無しさん :01/11/29 09:25
>>825 tclぶっ潰そうっていう意図が見え見えだから。
好き嫌いの問題ではなく、 人がせこせこ作っているものを こともなげに壊そうとする連中は嫌いだと言っているに過ぎない。
>>829 wetだねえ。いや、否定はしないけど。
でもさ、guileがtclを話せるようにすれば、
guileの中でtclは生きるわけで。
(でもって、その逆は無理なわけで。)
やっぱりtclが非力すぎるのが問題なんだと思う。
生きるとか生きないとかなんてのはどうでもよくて、 その意図が嫌いなんだよね。 Stallmanのある種の大人気無さが。
俺は好きだよ、Stallmanの大人げなさが。 っていうか、そんなことがguileの普及を妨げている理由だと本気で考えてるの?
tcl が駄目ってのは単なる例えなんじゃないの? それをつぶすのが目的ってことはないでしょ
俺がguileをあんまり使わない理由を述べただけ。
実際のところは、lisp系の言語が普及しないのと
同じような感じだろ。
>>833 tclのいる立場にとって代わろうと言うのは紛れもない事実だ。
それをつぶすといわずしてなんと言おう。
>>834 ほかのフリーソフトの地位を奪おうっていう例は
べつに珍しくないんじゃ? GNONMEとKDEとかさ。
とあるソフトの機能だとかパッチとかのレベルになると、
完全に正面対決してたりするんでは。
>俺は好きだよ、Stallmanの大人げなさが。 漏れも。 でも、この件に関しては大人げないとは思わないけどね。 拡張言語に tcl を使わず guile を使おうってのは ただ単に、(重要なところで)より良いモノを使おう(作ろう)って発想だし。
話が違う方向に行きそうだが、
gnomeとkdeは違う。
>>836 んじゃ、使えばいいだろ。
別にそのことまでいやだといっているわけではない。
個人的な感覚の問題さ。
>>837 ん?gnomeとkdeはそりゃ違うに決まってるがそれがどうした?
同じだといってるやつなんていないぞ。
個人的な感覚だからしょうがないのかもしれないが、
君の感覚はちょっと変だな。
いいものを使えるようにしようとしてるのを大人気ない
と思うなんて。
839 :
デフォルトの名無しさん :01/11/30 12:46
840 :
デフォルトの名無しさん :01/11/30 12:53
>>838 というか、どう言う経緯でそのような理解になったのかを
詳細に説明してください。
俺は838じゃないけど、 829=831=840はtclが非力かどうかとか、拡張言語とはどうあるべきかとか、 そういう話は別として、RMSの態度が気に入らないって言ってるんだよね? それはあなたの勝手ですし、RMSの態度が気に入らない同志を探してもいいし、 RMSが人を傷付けたということをアピールしてもらってもいいけれど、 なぜGuileが流行らないかという問いかけに対するフォローとしてはお粗末じゃないかしら。 RMSがもっと別の言い方でGuileをアピールしたとしても、 結局tclキラーとして登場することには変わりがない。 RMSの主張が間違っている、Guileよりもtclの方が良い、という意見なら、 興味深いけど、RMSの態度が気に入らないといだけではね。 もっとジェントルにGuileが登場したとしても、本質的にtclと衝突するわけ だから、結果はいっしょだと思うんだが、そこところはどうですか。
>>839-840 俺は
>>837 のほうこそ意味がわからない。
stallmanがtclを潰そうとしてるのが大人気なくて、
それが普及の妨げになってるのだろうと主張してるやつが
いて、その意見に対してよせられた主張が次の二つ。
・gnomeとkdeのように、他のソフトから地位を奪おうとするのは
珍しいことではない。
・tclより良いものを使いたいからguileを作っただけなのでは
ないか。
そして、それに対して、
>>837 がgnomeとkdeが違うなどと
意味不明の主張をしたわけ。
俺個人としては2つ目の反論と同じ意見で、大人気ないと
思うのは変だと思う。
>>841 が言うように、そう思うのは
個人の勝手だけどね。
>>841 >そういう話は別として、RMSの態度が気に入らないって言ってるんだよね?
>それはあなたの勝手ですし、RMSの態度が気に入らない同志を探してもいいし、
>RMSが人を傷付けたということをアピールしてもらってもいいけれど、
>なぜGuileが流行らないかという問いかけに対するフォローとしてはお粗末じゃないかしら。
>>834
後半については? むしろそっちが聞きたいんですけど。
このスレの人って結構泥沼の口論になりがちだな (藁
つーか、RMSとtclコミュニティのフレームに限らず、 過去に発生したフレームを蒸し返したら、泥沼になるに決まっている。
>>844 それに関しては大して興味がないとしか言えない。
848 :
デフォルトの名無しさん :01/12/01 02:43
新しい言語の大部分は以前あった言語と競合するものだと思うが、 それのどこが非難されるべきなのかわからん。 永久にCOBOLとFORTRANつかっとれ、とか?
849 :
デフォルトの名無しさん :01/12/01 04:50
前に正規表現で質問した者ですが, 正規表現がない実装系では text 処理は やらないものなんですか? perl みたいに使おうとするのは間違いかな?
>>842 第三者の立場から言わせてもらうと、837の意見は
「gnomeとkdeは(他のソフトから地位を奪おうとしているのとは)違う。」
という風にも受けとめられるということを一言、言わせてもらいます。
多分、その意味解釈の仕方で意見が分かれているように感じられたので。
ただし、もう一言付け加えるなら、
一読した時点では、私も838と同様な意味の受け取り方をしたことも付け加えます。
文を略すこと自体は悪くないが、
文脈上、837の略すタイミングが悪かったと言わざるを得ないです。
852 :
デフォルトの名無しさん :01/12/01 08:46
Schemeで並行処理やマルチスレッド処理を実装できますか。 処理のしくみを勉強したいんで、効率悪くてもいいです。
853 :
デフォルトの名無しさん :01/12/01 09:47
>>852 並行処理ってのはよく知らんけど、継続でなんとかなるのでは?。
call/ccでノンプリエンティブ(協調型)スレッド(=コルーチン)
なら作れるよ。
プリエンティブマルチスレッドが使えるかは処理系に依る。
854 :
デフォルトの名無しさん :01/12/01 09:49
>>852 schemeの本買えばたいがい書いてあるよ
継続使うやつね
立ち読みで確認してからゲット
>>850 838と同様な意味って言うのは、どんな意味だ?
838からはどんな意味かがわからん。
GNOME != KDE
ああ、なるほど そう言う意味か。 確かにそのレスの字面だけ追えばそうなるな。 しかし、他のレスも含めて考えればそうはならないと思うが。
>>857 いいかげんに荒らすのやめろよ。
君は個人的な感覚について表明したかっただけなんだろ。
君がそう感じているのはわかったよ。
でも、それを周知したところで誰にどんな得があるんだい?
↑ 誰かがguileが広まらない理由を聞いていたので 俺はそれに俺なりに答えただけだ。 それより他の意味はない。 下らんことを言うな。
技術話と、広まらないねぇとかって話は、( それぞれ続くなら)別のスレでやった方がいいんじゃない?
>>860 「なんでguileは広まらねえのか?を話し合うスレ」
立てていいって事?
862 :
デフォルトの名無しさん :01/12/02 18:41
最近scheme使ってるんだけど、 引用符付けただけでコードがリスト構造になるじゃん? これってすごくない?
>>862 最近C言語使ってるんだけど、
""で囲っただけでコードが文字列になるじゃん?
これってすごくない?
865 :
デフォルトの名無しさん :01/12/02 20:19
>>862 もっと震えるほど感動してもいいんだよ。
866 :
デフォルトの名無しさん :01/12/03 00:36
>>862 でも構文なめるときは解析が必要だろ。ifだったら
(define expr '(if test-part true-part false-part))
(cadr expr) => test-part
(caddr expr) => true-part
(cadddr expr) => false-part
867 :
デフォルトの名無しさん :01/12/03 00:58
Cだったら 文字列->トークンにするだけで一仕事って事でしょ。 しかもCじゃトークンを保持する汎用的な型なんて無いし。
868 :
デフォルトの名無しさん :01/12/03 01:12
でも文字列処理とか細かい処理書きづらい。 memchrみたいなオフセット操作なんか。
869 :
デフォルトの名無しさん :01/12/03 02:07
>>868 Schemeのライブラリは少ないけど、Common Lispなら文字列処理もかなり強力だよ。
文字列、リスト、ベクタをまとめたもの(列)に対して使える関数も多数。
;;; strの先頭からaという文字まで(なければ末尾まで)をコピーして返す。
(subseq str 0 (position #\a str))
;;; str中の.をすべて/に置き換える。
(substitule #\/ #\. str)
;;; strが(英字だけ見て、大文字小文字無視して)回文になっているか
;;; どうか判定する。(ちょっと無駄だが。)
(let ((s (remove-if-not #'alpha-char-p str)))
(string-equal s (reverse s)))
;;; str中にA-Zまでの英字(大小無視)を全て含んでいるかどうか判定する。
;;; (かなり無駄があるが。)
(= 26 (length (remove-duplicates
(remove-if-not #'alpha-char-p str)
:test #'char-equal)))
>>866 そうそう。それで、その時に全ての文が(関数 引数...)の形で
統一されてることが役に立つんだよ。
Lispのいいところは、'一つでリストになることではなく、
その上で文の形式が統一されてることにあるんだよ。
871 :
デフォルトの名無しさん :01/12/03 04:02
中西正和著Lisp入門って本を発掘したんだけど Lisp入門ってこれやっとけばOK?
古すぎ>871 それより最近出版されたMac寄りの分厚い本お勧め。
873 :
デフォルトの名無しさん :01/12/03 22:26
SCHEME初心者です。 例えば命題Pに対して否定命題をP'とするとP∨P'だと#t P∧P'だと#fみたいに評価するのってSCHEMEでは どう書くの?
874 :
デフォルトの名無しさん :01/12/04 00:18
>>873 pの値が分かっているとき、そこからもっと複雑な条件を判定したい
という意味なら
(and p (not p))
とか
(or p (not p))
とか書けば良い。
上が恒偽(恒真)であることを証明するという意味なら、証明系を
書かねばならない。
875 :
デフォルトの名無しさん :01/12/04 02:56
(define tautology? (lambda (sequent var) (eval `(let ((fun (lambda (,var) ,sequent))) (and (fun #t) (fun #f))) (null-environment 5)))) (tautology? '(or p (not p)) 'p) => #t
876 :
デフォルトの名無しさん :01/12/04 04:53
sちぇめなんかじつようてjきなあぷるけーdごんも書けないお遊び変後です。 しかも時代暮れ その点留byさいこー!!! rうbyいgへ胃の援護はいって吉!
877 :
デフォルトの名無しさん :01/12/05 00:39
>>868 schemeはstring-〜直接使うよりも
Cのポインタ操作のエミュレートでもした方が使い勝手いいと思うんだけど
(define p (make-ptr "abcdef"))
(* (++ p)) ;genericが無ければ ((p '++) '*)
==> #\b
(* p #\a) ;(p '* #\a)
==>#\a
(ref p 1 #\x) ;(p 'ref 1 #\x) ;p[1] = 'x';に相当
==>#\x
(write p) ;(p 'write)
"aaxdef"
イテレータですな。
879 :
デフォルトの名無しさん :01/12/05 10:12
Structure and Interpretation of Computer Programs 2nd の訳本買ったのですが、問題の答えありますか? ネット上を探したのですがみつかりません。
880 :
デフォルトの名無しさん :01/12/05 17:07
>879 それぐらいご自分で解きなはれ
答えあわせがしたいなら、ここに答えを書き込んでみれば、 みんなが添削してくれるでしょう。
882 :
デフォルトの名無しさん :01/12/05 23:11
>>879 どうして、指導マニュアル本も翻訳しないんだろ。
883 :
デフォルトの名無しさん :01/12/05 23:54
SICPの本文はネット上で公開されている(さすがMIT)けど、 Instructor's Manualの方は公開されてませんよね。 買うしかないか?
SICP の英文が難しくて, 日本語ならわかるかと思って買ったけど, 日本語も難しかった. 言語の問題じゃなかったんだな.
885 :
デフォルトの名無しさん :01/12/06 00:47
lispで質問です。 あるサンプルで (funcall '+ 1 2 3) というのがあって、これを (funcall #'+ 1 2 3) としても、動きました。「関数を引数で渡すとき#'をつける」と 何かで読んだことがあるのでやってみたのですが、この二つの違いはなんですか?
ちなみにxyzzyで実行しました。
887 :
デフォルトの名無しさん :01/12/06 01:48
>>882 , 883
Instructor's Manualは学校の先生だという証明がないと買えないよ.
888 :
デフォルトの名無しさん :01/12/06 04:05
>>885 CommonLisp ではどうか知らないけど,
Emacs lisp の manual では無名関数を
(function) で quote することによって
byte compile 時に関数としてコンパイルする
という説明があった.
#' というのは function の省略形ね.
889 :
デフォルトの名無しさん :01/12/06 10:10
>>Instructor's Manualは学校の先生だという証明がないと買えないよ ということは、独学でSICP読んでも、答え合わせの手段がない? とりあえず、問題無視して本文だけ読んじゃおうっと。
890 :
デフォルトの名無しさん :01/12/06 10:30
Instructor's Manual には解答は載ってないのでは?
891 :
デフォルトの名無しさん :01/12/06 11:40
解答の公開サイトURL、誰かどっかに貼って無かった?
(define (split s c) (let loop ((start 0)(pos (strchr s c))(r '())) (if pos (loop (+ pos 1) (strchr s c (+ pos 1)) (cons (substring s start (+ pos 1)) r)) (if (< start (string-length s)) (reverse! (cons (substring s start) r)) (reverse! r) ) )))
894 :
デフォルトの名無しさん :01/12/07 08:55
SCMってどうですか?
896 :
デフォルトの名無しさん :01/12/08 16:36
gcの実装方法なんですが、vectorでリンクリストを作ると、 gcの配列探索でのネストが深くなりすぎてスタックオーバーフロー でこけてしまうんですが、うまく探索する方法ないですか? ↓こういうvectorのデータ構造 #(#(#(#(#(#(#(#(#(#(#(#(#(#(.....)
>>896 何が原因なのかよくわからんが、
再帰を使っててスタックオーバーフローしてるのなら
gcを再帰を使わずに書きましょう。
898 :
デフォルトの名無しさん :01/12/09 16:49
おっしゃー!! DQIIIクリアしたんで次は「計算機プログラムの構造と解釈」だ。 というわけで掲載サンプルを全て実行可能なWin2k/XP用の処理系ってありますか? なるべくGUIな環境がくっついてないやつがいいです。
899
今だ!!900ゲットォォォォォ  ̄ ̄ ̄ ̄ ̄∨ ̄ ̄ ̄ (´´ ∧∧ ) (´⌒(´ ⊂(゚Д゚⊂⌒`つ≡≡≡(´⌒;;;≡≡≡  ̄ ̄ (´⌒(´⌒;; ズザーーーーーッ
>>898 そんなことも自力で調べられない奴がSICPを読破できるわけがない。
>>898 現在メンテされてる処理系なら多分どれ使っても大丈夫だよ。
904 :
デフォルトの名無しさん :01/12/09 22:40
SICPは良いと言われるが、アマゾンの評価はぼろぼろ。 あれはK&Rと同じで最後に読んだほうがいい。
905 :
デフォルトの名無しさん :01/12/09 22:58
はぁ?最後? 最後ってなんの最後だ? 人生の最後か?
>>905 いちいち説明しないとわからんのか。
さては貴様、コーダーだな?
907 :
デフォルトの名無しさん :01/12/09 23:16
アマゾンの評価なんて気にするな>903
>>903 アマゾンの評価じゃなくて自分の感想を書いてくれよ。
SICPはK&Rとはまったく別のレベルの本だよね。 K&Rは言語の解説だが、SICPは違う。 Schemeは単に採用されているだけで、Schemeの解説本じゃない。 コンピュータ科学の本だからな。
エェ?>909
>910 でもさ、scheme採用しなかったらあの本書けるのかな?
914 :
SICP Isn't Computer Program :01/12/09 23:51
SICSの評判ますます上がる。 ↓ 厨房もどんどん読み始める。 ↓ 手に負えない人が不満を垂れる。 ↓ 理解できない腹イセにamazonで悪くいう。 ↓ (゚д゚)マズー ↓ 厨房は読まなくなる。 ↓ 正当な評価に戻る。 ↓ (゚д゚)ウマー
>>913 ん、例えばあのほんの内容をRubyですげ替え可能か、とか?
916 :
デフォルトの名無しさん :01/12/09 23:54
>>913 例えばJava。同じ内容を扱うと最低でも三倍の厚み。
4章あたりの内容が「電卓の作り方」に降格されるカモナー>915-916
かといって、あの厚さに収められるschemeはスゴイ、ってわけじゃあ ないんだよ。適材適所なのよ。 Ruby荒しクン達はその辺判ってないね。
誰かこのスレからRuby厨等の糞共の発言抜いて tar玉にしてうpしてくんない?
ていうか、Amazonだとこの本めちゃめちゃに叩かれてるな・・・ はっきりいって非常に評価低いよ。
921 :
デフォルトの名無しさん :01/12/10 07:38
でも、所詮プログラミングの経験の全くない学部1年生用の教科書なんだか ら、ある程度の素養のある人が読んだらつまらないですよ、SICP。もちろ ん入門レベルの教科書としては最高だと思いますけどね。重点は、コンピュ ータを使って問題をいかに定義して解くか、にかかっているわけだし。そう いう意味では、あれが計算機科学、というのはかなり変。なぜ日本だとこれ ほどまでに持ち上げられるのかわからない。 Amazonのレビューに関して言えば、大学でSICPを使った講義を取って、 ゴリゴリ宿題を解かされた挙げ句Cを食らったような人達が悪く書いている のでは?(ちょっと邪推すぎるか) 五つ星を付けている人も結構いるし。
922は卑屈な権威主義者
SICP が、日本で評判いいのは、あんまり教科書に使われてないからじゃない。 半期の講義で、演習問題ぜんぶ解け、とか言われてたら嫌いになってたかも。
925 :
名無しさん@ソウダソツケンヤロウ :01/12/10 15:08
LISPの質問ですが (1000 円) ってリストがあったとして、この1000の数字を半角数字に直す方法ってありますか? xyzzyスレにあったの1桁だったから…
926 :
デフォルトの名無しさん :01/12/10 15:10
cygwinで動くscheme処理系のバイナリあるとこ教えて
なんでわざわざcygwinなのかな
929 :
BASICER :01/12/10 17:26
>>925 まず、それってシンボルなの? 文字列ではなく?
第二に、そういう処理をする出来合いの関数が欲しいって話?
それとも、そういう処理をする関数の書き方がわからないって話?
>>930 説明不足スマソ
データは文字列でもシンボルでもどっちでもいい
あと既存の関数があればそれを使用したいけど残念ながら見つけられなかったので
あれば教えて欲しい
無ければそれを処理できる関数作るヒントくださいw
>>931 map-to-half-width-string とか。
つーか xyzzy スレできけばいいのに、とか。
Emacs では japanese-hankaku-region
>>932 ,933
情報サンクス
また説明不足(汗
使ってるのはGCLです
EmacsもろくにしらないLINUX初心者なもんでw
#というかxyzzyだと引継ぎのプログラムが動かないのでLINUXを導入した
最初はLINUXのEUCとWINDOWSのS-JISの所為かと思ったのだがそれだけではなかったらしい
引継ぎのプログラムのため大部分がブラックボックスw
あと3ヶ月か(;´Д`)
チョト試してみます
935 :
デフォルトの名無しさん :01/12/10 21:55
lispのソースってメンテしずらくない? 見た目だけ? 作るのは楽そうだけど、他人のソースをスラスラ読める人いる?
聞くだけなのもなんなので一桁変換なら (defun number_change (x) (cond ((eql x '0) (setf x '0)) ((eql x '1) (setf x '1)) ((eql x '2) (setf x '2)) ((eql x '3) (setf x '3)) ((eql x '4) (setf x '4)) ((eql x '5) (setf x '5)) ((eql x '6) (setf x '6)) ((eql x '7) (setf x '7)) ((eql x '8) (setf x '8)) ((eql x '9) (setf x '9)) ) ) まぁこの程度の知識しかないです(;´Д`)
937 :
デフォルトの名無しさん :01/12/10 22:09
>>936 なんか頭悪い気がするんだけど、気のせいでしょうか。
938 :
デフォルトの名無しさん :01/12/10 22:15
といいつつジブンもあんま変わらないかも (define (number_change x) (cdr(assq x '((0 . 0)(1 . 1) (2 . 2)(3 . 3) (4 . 4)(5 . 5) (6 . 6)(7 . 7) (8 . 8)(9 . 9)))))
939 :
デフォルトの名無しさん :01/12/10 22:30
テーブルがfixedなassoc系関数は、コンパイラがもっと速い 手段にすげ替えてくれるとうれしいんだけど。
940 :
デフォルトの名無しさん :01/12/10 22:38
リスト遊ビマンセー (defun 線路は続くよどこまでも () (線路は続くよどこまでも))
>>937 事実です(藁
二桁以上はどうするかってはなしで…
めんどいからその部分だけC言語使おうかな
942 :
デフォルトの名無しさん :01/12/10 22:52
>>941 lispはシンボルを使って何かするのは得意だけど、
そのシンボルを分解したりするって処理は向いてないんじゃないかな。
lispでやる利点なさそうだし。
その辺のトークンの問題はreaderの時点で解決してるべき。
943 :
デフォルトの名無しさん :01/12/10 22:57
>>941 GCL でどーかはわからんが。
(defun hoge (str)
(map 'string
#'(lambda (c)
(if (char<= #\0 c #\9)
(code-char
(+ (char-code #\0)
(- (char-code c)
(char-code #\0))))
c))
str))
(hoge "12345あいう")
"12345あいう"
>>943 おお、VeryThx!
明日にでもGCLで試してみます!
カールってもう食べた人いる?
946 :
デフォルトの名無しさん :01/12/11 01:14
「型なし言語逝ってよし」というスレを読んでて
思ったんだけど, lisp ってビジネス用途に
多人数で共同開発する場合はどうなんでしょうか.
自分で作る分には楽しいんだけど,
保守とかデバッグはどうなんだろう.
>>935 とも関係ある話だけど.
>>946 いまや大企業でも多人数は珍しいですよ。せいぜい10人じゃないですか?
3,4名の開発がほとんどでは?
AgileAllianceにみられるように、変化につよい、小回りの利く
開発手法はお客さんも求めてるなぁと日々実感してますよ。
Perl,SmallTalk,Python,Ruby,Lisp,Java,C++,Cを
適所適材っつーかんじで
組織やチームの文化も考えて使い分けるのがいいのじゃないの
でしょうか。
前置きながくなったけど、ペアプログラミング可能な言語だと思うので
メンタリングといゆか教えるのが好きで皆から信頼されてる
プログラマがチームに1人いるならLispはOKでしょう。
保守、デバッグについては、Unitテストを活用すべし。でしょう。
948 :
デフォルトの名無しさん :01/12/11 03:21
>>944 別解
(defun hoge (str)
(map 'string
#'(lambda (c)
(let ((pos (position c "0123456789")))
(if pos (char "0123456789" pos) c))
str))
(しかし、EUCの2バイト文字を1文字と扱えるのか?ダメだと思うが…)
>>942 つーか、シンボルは分解するようなものじゃないだろ?
>928-929 わざわざcygwin版探してるのは挙動が素直そうだからです SCMはDOSアプリだしMIT版は謎の独自コンソールだし 他のは不安定なGUI版だしで処理系探しに疲れました...
>>950 Guileは?
あと、SCMをcygwinでコンパイルするとか。
>943 xyzzyだと動作確認できたけどGCLだと無理みたいです エラー内容 >Error: "0" is an illegal character name. >Fast links are on: do (si::use-fast-links nil) for debugging >Error signalled by LOAD. >Broken at LOAD. Type :H for Help. やっぱ2バイト文字は認識されないのか
結局makeは諦めてPetite Chez Scheme(
http://www.scheme.com/ )に落ち着きました。
# それにしてもこんなドメイン使っていいのか?
入力用のプロンプト"> "を標準出力に吐くのが気になりますが
Windowsのアプリとしては一番挙動がまともっぽいです。
CygwinでもDOSアプリって動かせない?
>954 Cygwin(というかbash)から16ビットDOSアプリの起動・実行は問題なく出来ます。 ただ、一般的に16bitの処理系にはいろいろ制約があることが多いのでなんとなく避けたかったんです。
今日は次スレ日和ですな
957 :
デフォルトの名無しさん :01/12/12 09:01
>952 こんなのはどうですか? (defun agi (str) (labels ((agi% (new-old-alist list) (if (endp new-old-alist) list (let* ((new (caar new-old-alist)) (old (cdar new-old-alist)) (pos (search (map 'list #'identity old) list))) (if pos (agi% new-old-alist (concatenate 'list (subseq list 0 pos) new (subseq list (+ pos (length old))))) (agi% (cdr new-old-alist) list)))))) (map 'string #'identity (agi% '(("1" . "1") ("2" . "2") ("3" . "3") ("4" . "4") ("5" . "5") ("6" . "6") ("7" . "7") ("8" . "8") ("9" . "9") ("0" . "0")) (map 'list #'identity str))))) (setq yen "1231234567890円") (agi yen)
958 :
デフォルトの名無しさん :01/12/12 18:49
ケント・ディヴィグのプログラミング言語Scheme読んでるけど、 これって難しいよね? Schemeのことについてあらかじめ知ってないと、あの説明では 理解出来ないと思う。 でも、Schemeを知ってる人が知識を確認したり、知識を磨くの には素晴らしいのは確かだと思う。 C++におけるプログラミング言語C++と同じような立場の本だね。
>>957 いまGCLで動作確認しました。本当にありがとうございますm(__)m
ところで、ここにいるLISP使ってる人達ってLISP歴どのくらいなんだろう(汗
私は半年ですけど・・・
960 :
デフォルトの名無しさん :01/12/12 21:33
>>958 あの本は Lisp 系 の基本を知らないと難しいが,
知っている人なら当り前のことで簡単過ぎるような気がする.
基本的な概念への入門的な説明が少ないような気がする.
continuation の概念なんか, 本文の説明よりも付録の R5 を
読んだ方がわかりやすかった. 一度理解してから本文を読むと
なにを言っているのかわかるんだけど.
という訳で, 個人的には中途半端な本のような気がする.
ただリファレンスとしては便利だと思う.
あの本は、うまいコードが載ってる気がするけど、 コードの解説はあまりしてないから読むのに苦労する。 作者のオナニーにしか見えん。
962 :
デフォルトの名無しさん :01/12/12 22:32
標準的な本でしょう。 よくある「プログラミング言語○○」の一種。 SchemeはこれとSICPと入門本でとりあえずOK。
963 :
デフォルトの名無しさん :01/12/12 22:56
Schemeの入門は「Scheme手習い」直感で学ぶLisp が良かったです。 Lispの概念は「初めての人のためのLISP」(竹内郁雄=著)が奥深いと思います。 いずれも絶版なのが残念です。
964 :
名無しさん@Emacs :01/12/13 02:31
>>963 初めての人のためのLISPはいいですね。
対話形式で話が進むので最初しまったと思いましたが。
「Schemeの手習い」はLittle Schemerの訳本ですね。 原著でも、むずかしい英語じゃないし (っていうか、それ以前に文章量が少ないし) 原著で読めばいいんじゃないですか? ちなみに僕はLittle Schemerを読んで Scheme好きになりました。
誰か次スレ立てて下さい
968 :
ななしさん :01/12/13 13:36
>>921 アメリカのComputer Scienceの人にも評価は高いよ。
streamの導入のあたりはなんど読んでもぞくぞくする。
でも今は教育用の言語としてはJava一人勝ちだからね。
ありがとう>967
誰かSIRをXLisp-statで走らせた方います???
まもなくここは 乂1000取り合戦場乂 となります。 \∧_ヘ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ,,、,、,,, / \〇ノゝ∩ < 1000取り合戦、いくぞゴルァ!! ,,、,、,,, /三√ ゚Д゚) / \____________ ,,、,、,,, /三/| ゚U゚|\ ,,、,、,,, ,,、,、,,, ,,、,、,,, U (:::::::::::) ,,、,、,,, \オーーーーーーーッ!!/ //三/|三|\ ∧_∧∧_∧ ∧_∧∧_∧∧_∧∧_∧ ∪ ∪ ( ) ( ) ( ) ) ,,、,、,,, ,,、,、,,, ∧_∧∧_∧∧_∧ ∧_∧∧_∧∧_∧∧_∧ ,,、,、,,, ( ) ( ) ( ) ( )
記念カキコ。 今まで、C/C++, perl, java, elisp とかじってきたけどこれから scheme 信 者になります。scheme カコ(・∀・)イイ!! 立派な schemer になれますように。
975 :
cmlisp :02/04/26 00:05
>>761 cmlisp は、CM-2 で実装されました。しかし、data paralle な計算の
Nest が高速に扱えず速度が出ないため、Thinking Machines から商品と
して売られることはありませんでした。その後、CMU の Guy Blelloch
によってこの問題の解決手法が提案され NESL という言語があります。
NESL はフリーで手に入ります。MPI にも対応しているようなので
PC Cluster で NESL を動かせるかもしれません。
>>975 > cmlisp は、CM-2 で実装されました。
それは、*Lispじゃない?
Connection Machine Lispは、SIMDじゃ実装しにくいからね。
αapplyとかね。
test
u
u
u
u
u
u
u