1 :
デフォルトの名無しさん :
02/03/16 02:00
2 :
デフォルトの名無しさん :02/03/16 02:00
6 :
デフォルトの名無しさん :02/03/16 02:15
スレ立てお疲れ様です。 Smalltalk スレで、Smalltalk のリフレクションは Lisp 系起源という話が あったのですが、これって Common Lisp とかでしょうか? Scheme にもありますか?
7 :
デフォルトの名無しさん :02/03/16 02:19
お疲れ様ですげっとー!!
今日から guile をガリガリ覚えます。 ってただ言いにきただけ。scheme は何でもできて(・∀・)イイ!!みたいな意見 を前スレで見たので(実は難しくてあんまり読んでないけど) 楽しみ。
CLOS では intersession や introspection が可能らしいんだけど。
10 :
デフォルトの名無しさん :02/03/16 03:04
こういう特定用途のmapってschemeだと自分で定義するしかないけど、 CommonLispで同型関数ありませんか?(関数名を参考にしたいので) ;先頭からn番目までのリストをコピーして返す (define (list-head l n) (let loop ((l l) (n n)) (if (zero? n) tail (cons (car l) (loop (cdr l) (- n 1))) ))) ;リストがn以上の長さであれば#tを返す (define (nlength? n l) (if (zero? n) #t (if (pair? l) (nlength? (- n 1) (cdr l)) #f))) ;n個引数ずつ処理するmap (define (mapn n proc l) (let loop ((x l)) (if (nlength? n x) (cons (apply proc x) (loop (list-tail x n))) '()))) ;n個引数ずつ処理するmap。 ;引数はコピーされるので可変個procに対してのapplyも安心 (define (mapnc n proc l) (let loop ((x l)) (if (nlength? n x) (cons (apply proc (list-head x n)) (loop (list-tail x n))) '()))) ;使い方 >(mapn 3 (lambda x (apply + x)) '(1 2 3 4 5 6)) =>(21 15) >(mapnc 3 (lambda x (apply + x)) '(1 2 3 4 5 6)) =>(6 15)
> ;先頭からn番目までのリストをコピーして返す subseq > ;リストがn以上の長さであれば#tを返す nthcdr
12 :
デフォルトの名無しさん :02/03/16 17:03
guile で step 実行とかやりたいんだけど info 見たら何も書いてなかった。 cvs でとってきた 1.7 なんですけど。これって make 失敗とかですか?もと もとないんですか?
>>8 Scheme の良いところは、言語仕様を覚えるのが楽って事かな。
あとはマクロか。これがデカい。タイプ量が減るので最高。
ライブラリは適当に出回ってるのでも使って頂戴。
やっぱり gauche の方がおもしろそうなので乗り換えます(w でも slib が使えるようにならないなぁ。インストールばっかりやってると時 間がもったいないから slib は後まわしで scheme 覚えよ。
15 :
デフォルトの名無しさん :02/03/17 03:11
>>14 guileのinfo読めば書いてあるのに。
>>15 いや、guile からは slib 使えるようになったんですけど、gauche
の方が... もうちょっと調べに逝ってきます。
C は「手続き型」なのに「関数」 scheme は「関数型(?)」なのに「手続き」 なんかおもしろいね。間違ってたらツッコミよろしく。
18 :
デフォルトの名無しさん :02/03/17 12:02
>>17 前者は手続きを含むプログラムで言う所の「関数」
後者は写像の意味の「函数」の一般的な表記
ちょとちがう。
20 :
デフォルトの名無しさん :02/03/17 12:18
gaucheは./configure --helpすれば書いてるよ slibのパスを設定すれば何とかなるんでない? 俺は試してないけどね。
SICPの問題にでてくる登場人物の名前ってどこから とったんだろう。気になって夜もねむれません。教えてセソセイ!
23 :
デフォルトの名無しさん :02/03/17 13:24
C言語を始めようと思って、コンパイラ(BCC)をダウンロードしました。 C言語は解説してるページもけっこうありそうなので、それを参考に勉強していこうと思ってのですが、 無理です...... やっぱり解説書を買うべきでしょうか。
>>23 逝ってよし
誤爆は無視して 行きましょう
>>21 xyzzyはEmacs LISPじゃないょぅ
xyzzyはcommon lisp風ですね
27 :
デフォルトの名無しさん :02/03/17 16:24
>>21 俺は「リスト遊び」読んでから、URL の1個目の人が書いてる「やさしい
Emacs-Lisp 講座」を読んだよ。「やさしい...」読んだら人のソースとかも読
めるようになる...かな?俺も勉強中。
slib のインストール挫折しました。 gauche で slib 使えてる人教えてください。 Gauche-eucjp-0.5.2-1 の rpm なんですが、/usr/local/silb から slib を探 しているようなので、ln -s /usr/share/slib /usr/local/slib とシンボリッ クリンクしました。それから gauche を起動すると、 gosh> (use slib) *** ERROR: no such module: srfi-1 Stack Trace: _______________________________________ 0 (%require feature) At line 34 of "/usr/share/gauche/0.5.2/lib/gauche-init.scm" のようになります。srfi-1 を探すと /usr/share/slib/srfi-1.scm /usr/share/gauche/0.5.2/lib/srfi-1 というのが見つかるのですが。どうしたらいいんでしょ。
>>20 --with-slib=PATH ですよね。ソースから make も試したのですがだめでした。
;; 何が悪いんだろ。もう1回 make してみようかなぁ...
>>25 >>26 そうなんですか・・! Emacs Lisp ⊂ Common Lisp だと思ってました。
そういえば、xyzzy は Common Lisp だとどこかで読みました。
Emacs Lisp と Common Lisp、とりあえずどちらを学ぶのが
良いのでしょうか。
より一般的にエディタに使われている方を学びたいと考えてます。
つまり、どちらの言語でライブラリを書くと、より多くの人に
(特に英語圏の方に)使ってもらえるでしょうか。
そりゃ当然 Emacs lisp でせう。
>>32 どうしてですか?
どうぞ教えてくださいませ。
(一般論でなくても、俺的意見でも何でも・・)
>>31 Emacs Lisp だけ覚えても、良いプログラムが書けるとは思えない。
まずは Common Lisp か Scheme で修行して、Lisp の本質を勉強する
事をオススメする。
>>34 Scheme なら大学の授業でとりました。
これならおっけいですか?
>>35 素晴らしい。Emacs の世界に貢献して下さい!
40 :
デフォルトの名無しさん :02/03/18 21:48
きだあきらがSICPをCマガで紹介してた
gauche で slib 使ってるシト教えてよぉ...
42 :
デフォルトの名無しさん :02/03/18 22:17
>>40 scheme 特集あるの?立読みしに逝こ。
43 :
デフォルトの名無しさん :02/03/18 22:38
>>42 そんなたいそうなもんじゃない
単なる書評
Great !っていう内容の
44 :
デフォルトの名無しさん :02/03/18 23:49
scsh使ってる人いる?今マニュアル読んでるんだけど。 おもしろい?
45 :
デフォルトの名無しさん :02/03/19 02:39
guile-gtk は cygwin では使えないんだよね?
>>42 もしscheme特集やるとして、何載せるんだ?
どうせCマガのことだからlambdaとかtailrecurseみたいな
初歩的な事しかやらないだろ。
末尾再帰の練習に fibonacci 数計算してみた。 あってる? 修行が足りない? (define (fibo num) (define (loop n p1 p2) (cond ((= n 0) 1) ((= n 1) 1) ((= n 2) (+ p1 p2)) (else (loop (- n 1) (+ p1 p2) p1)))) (loop num 1 1))
48 :
デフォルトの名無しさん :02/03/19 13:30
Cマガで特集? それはやっぱアサインメントを使用しないで アルゴリズムを構築するってことの妙味を伝えるんじゃないかな?
>>44 さわった事あるよ。
でもC-z等が使えないので、bashにとってかわる事は出来なかった。
50 :
デフォルトの名無しさん :02/03/19 16:32
C-zて何よ
suspend とか?
make して ./go してみたけど使い方が分からんかった(w
53 :
デフォルトの名無しさん :02/03/19 20:37
すsぺんdなら継続をぶった切ればいいじゃん
盛り上がらないなぁ、lisp, scheme スレ。
Schemeの評価は確立されたものだよね。 あとは「より良いライブラリ」についての議論ぐらいじゃないの?
56 :
デフォルトの名無しさん :02/03/19 22:52
Scheme/Lisp のオブジェクト指向ってメソッドがクラスに従属していない って言うけど、良く判らない。クラスの内部にアクセスする手段というのが、 メソッドの一つの役割ですよね。メソッドをクラスの外で宣言できるという 事はオブジェクトの隠蔽と矛盾しないのでしょうか? って、自分で調べてみろって? そうします・・・。
Bertrand Meyerも書いているけれど、オブジェクト指向の定義は これといったものがないんだよね。人によって定義が違うわけ。だ から、ある人にとって「こんなのオブジェクト指向じゃない!」と 言えるものが、ほかの人にとっては「まさにこれこそがオブジェク ト指向だ!」となることもあるわけ。 メソッドの定義を隠蔽するかどうか、アクセス制御を提供するかど うか、といったあたりはOOPLによってかなり幅のある部分ですよね。
58 :
デフォルトの名無しさん :02/03/19 23:15
60 :
デフォルトの名無しさん :02/03/19 23:50
>>56 LISPやSchemeではオブジェクトやメソッドとかの隠蔽って
自然に出来ると思うけど?
特にこれといったインターフェースを使え、とか強要されて
るわけでもないし、制限も別に無いんで、頭やらかい人じゃない
と逆に使いづらいのかも。
61 :
デフォルトの名無しさん :02/03/19 23:58
例えば、単にclosureの中に置けば隠蔽したことにならない? それと「メソッドがクラスに従属していない」のは CLOSみたいなマルチメソッドを採用してるパッケージだと思う。 もちろん、C++やJava風の、クラスに垂れ下がるメソッドを持つ 形式のパッケージもあるよ。
62 :
デフォルトの名無しさん :02/03/19 23:59
56ではないのですけどメソッドのディスパッチの方法はどうやってるの? くわしい人解説プリーズ。
63 :
デフォルトの名無しさん :02/03/20 00:31
>>62 CLOSのディスパッチ方法は・・・
最初に、ある名前に対して
「この名前をメソッド(=総称関数)として使用する」
と宣言する。(必ずしも名前を定義する必要はなく、lambdaと同様に無名メソッドも定義できる。)
するとメソッドディスパッチを行うオブジェクトが生成され、その名前に関連付けされる。
そのオブジェクトはメソッド毎のクラス階層と依存関係を保持していて、
新しいメソッドが定義されると、その依存関係を更新する。
メソッド呼び出しで、ディスパッチオブジェクトが引数に与えられた
各オブジェクトのクラスを比較していき、クラスが一致するか、
または与えられたオブジェクトがそのクラスの派生型である
メソッドを選択して適用する。
64 :
デフォルトの名無しさん :02/03/20 00:40
CLOSでは無名メソッドが許されているため、 名前よりもむしろ引数型の組み合わせが重視される。 ローカル宣言もできるので、名前を外部に公開しなければ 隠蔽の意味にもなるでしょ。
65 :
デフォルトの名無しさん :02/03/20 20:24
CLOSの参考書おしえて!
今更 part2 を読んできました。懐しかった。今読んだら意味が判る(ところも あった) ところで、 scheme の「手続き」は closure で、 closure とは「環境」のついてくる「(Cでいうような)関数」で、 「環境」とはその時点で存在する変数とその値、手続きなどの alist (のようなもの) っていう理解であってる?間違ってたら指摘プリィズ。
67 :
デフォルトの名無しさん :02/03/21 15:50
alistってなに?
68 :
デフォルトの名無しさん :02/03/21 15:59
(define-macro(apush key data table) (set! table (cons (cons key data) table))) (define (table '()) (apush 'これが 'alistや! table) (assq 'これが table) =>(これが . alistや!)
69 :
デフォルトの名無しさん :02/03/21 20:48
コンパイラ入門の本をみてみると、再帰下降法がのっていた。 「強力な手法」とのこと。 やっぱり、構文の再構成に使用するデータ構造はリスト構造が最適なのでしょうか。 それとお聞きしたいのですが、 LISPと数式処理、LISPと有限群論について何か良い本、Webページはないでしょうか。
70 :
デフォルトの名無しさん :02/03/21 23:02
71 :
デフォルトの名無しさん :02/03/22 02:18
FAQ 見たけどやっぱ slib が使えないぞ俺には...(鬱 *** ERROR: no such module: srfi-1 Stack Trace: _______________________________________ 0 (%require feature) At line 34 of "/usr/share/gauche/0.5.2/lib/gauche-init.scm" なんでこうなるんだよう。教えてくれよう。 SCHEME_LIBRARY_PATH 設定したのにだめ。
あ、gauche の話です。 slib 使えなくても多分問題はないんだけど...気になる。
あ、わかった。 (use srfi-1) (use srfi-2) .... (usr slib) ってひたすらやったらエラーは出なくなったけど... (use slib) だけでできるってマニュアル書いてあったから本当は自動でやっ てくれたりするんじゃないの?
75 :
デフォルトの名無しさん :02/03/22 09:58
LISPはいい。 複雑な構文もない。 演算子もない。よって優先順位もない。 書いた文はそのままリストになるし。 リストをevalに書ければ評価される。 非常にわかりやすい。 カッコ付けるだけで、なんでもできる気がする。
76 :
デフォルトの名無しさん :02/03/22 10:07
LISPとFORTHどっちが簡単か? と問われたら、俺は間違い無くLISPと答えるだろう。 つーかFORTHわけわからん。 LISPが一貫して (<関数|構文> 引数) なのに対し、 FORTHは暗黙のスタック操作も含まれるため、 引数 <関数|構文> だけでは済まされない事が、問題を複雑化してる様に思う。 コードを読んでも、そのときスタックに何が積まれている(べきな)のか、 俺にはさっぱりわからないのだ。
とはいえ、OpenBootがgarbage collection始めたらイヤだよね。
FORTHは人間にとって優しい言語ではなく、 処理系実装者にとって優しい言語だと思われ。
>>78 LispもFORTHほどじゃないが処理系実装者にとって優しい言語だと思う。
邦訳の ANSI Common Lisp はまだ出てないかな?
>>81 ガーソ。 未定っていつになるんだろう...
出版中止にだけはなりませんように
84 :
デフォルトの名無しさん :02/03/22 23:59
>>83 学校の授業でDrScheme使うのか。
課題がPICコンパイラつーのは面白そうだな。
85 :
デフォルトの名無しさん :02/03/23 00:29
fluid-let マクロで作って。
86 :
デフォルトの名無しさん :02/03/23 00:31
>81 訳本で未定ってどういうこと? まだ翻訳が終わってないのか、 金の問題なのか。 後者だったらやだなあ・・
87 :
デフォルトの名無しさん :02/03/23 00:37
>>85 fluid-letって初出どこだったかな。
define-macro版とsyntax-rule版がを見かけたことあるけど。
そういや、fluid-let内で継続脱出があった場合、
どういう扱いになるか、誰か知ってますか?
>>85 Slib にあったよ。チラっと見たら、dynamic-wind 使ってました。
89 :
デフォルトの名無しさん :02/03/23 00:52
define-macro版のfluid-let。 どっかから持ってきたやつをちょっと修正したもの。 R5RSのdynamic-windが必要。 この実装だと継続脱出が起こると前の状態に戻る。 (define-macro fluid-let (lambda (xexe . body) (let ((xx (map car xexe)) (ee (map cadr xexe)) (old-xx (map (lambda (ig) (gensym)) xexe)) (result (gensym))) `(let ,(map (lambda (old-x x) `(,old-x ,x)) old-xx xx) (dynamic-wind (lambda() ,@(map (lambda (x e) `(set! ,x ,e)) xx ee)) (lambda() ,@body) (lambda() ,@(map (lambda (x old-x) `(set! ,x ,old-x)) xx old-xx)))))))
90 :
デフォルトの名無しさん :02/03/23 01:01
resultは余計だった。
>>86 んー,なんでだろ。たしか去年の11月ぐらいから近刊案内
には載ってたから金ではない気も。単に翻訳の遅れと思い
たい。
お前ら scheme 処理系は何使ってらっしゃいますか?自作ですか?初期設定ファ イルには何を書いてますか?
>>92 自作が多いと思われ。
1)最低限の実装以外は全部schemeマンセー
2)可能な限りCやASMで組み込み症候群
の2派が存在すると思われ。
その中でもEXE作れる処理系はごくわずかと思われ。
94 :
デフォルトの名無しさん :02/03/23 01:58
>>94 delay/force を頻繁に使ってます。lazy list って何?
lazy list を www.dict.org で調べました。失敬。
連続 sorry
>>94 lazy list の説明に、
A list which is built using a non-strict constructor.
(non-strict なコンストラクタを使って構築されるリスト)
ってあるんだけど、Scheme は strict じゃないの?
98 :
デフォルトの名無しさん :02/03/23 02:30
>>97 a non-strict constructor → delay
"un-evaluated objectをconstructする。"
>>98 なるほど。お馬鹿な質問をしてしまいました。
100 :
デフォルトの名無しさん :02/03/23 02:53
>>100 納得できる内容なら信用すれば良い。
(すごいとは思ったけど何処まで重要なのか私には和歌欄……)
「なぜ関数プログラミングは重要か」は、たしかに目からうろこだったよ。 これを読むまでHaskellがどうして遅延評価にこだわっているのか、わか らなかったし。 Schemerとしては、リスト構造や高階関数の価値がわからないプログラマ に対して「こんな良いものがわからないなんて...」という気分を持って いますから、Haskell派の方々が遅延評価について同じような気持ちを 抱いているであろうことはわかりました。ただ、Haskellは僕にはわけが わからないんで、しばらく使う気はありませんけれど。
103 :
デフォルトの名無しさん :02/03/23 08:33
ここで関数型の話をするのもなんだけど、 「遅延評価が重要だ」が先にくるんじゃなくて、作用順序に依存しないコード の方が保守性が良くなるんじゃないか、って考えが元なんじゃないかと。 haskellはそれを体現してみせたわけだけど、結局、 モナドなんかはやりすぎって感じで、本末転倒な気がするのは俺だけでしょうか。
104 :
腰の曲がったおじいさん :02/03/23 12:09
AlgolやPascalだって昔はやりすぎに見えたよ。
> (define (length l)
(cond
[empty? (l) 0]
[else (+ 1 (length (rest l)))]))
cond: clause is not in question-answer format
>
ランゲージレヴェルスエクザンプルの1ページ目に載ってた関数を実行したら
こうなったDrSchemeをうかつにDLしたが、サパーリちんぷんかんぷん
誰か乞うアドバイス
>>104 C++は今がやりすぎだね(w
106 :
デフォルトの名無しさん :02/03/23 14:27
>>105 setpperつかったら?
(length (1 2 3 4))とかやってみてみそ
107 :
デフォルトの名無しさん :02/03/23 14:31
(length (1 2 3 4)) (+ 1 length(2 3 4)) (+ 1 (+ 1 length(3 4))) (+ 1 (+ 1 (+ 1 length(4)))) (+ 1 (+ 1 (+ 1 (+ 1 length())))) (+ 1 (+ 1 (+ 1 (+ 1 0)))) =4
>>106 えっ?
> (length (1 2 3 4))
illegal application: first term in application must be a function name
> (length (1 2 3 4))
(+ 1 length(2 3 4))
(+ 1 (+ 1 length(3 4)))
(+ 1 (+ 1 (+ 1 length(4))))
(+ 1 (+ 1 (+ 1 (+ 1 length()))))
(+ 1 (+ 1 (+ 1 (+ 1 0))))
illegal application: first term in application must be a function name
>
こりゃだめだ!!
DrSchemeが嫌いになりそ(@_@);
SICP プリントアウトしたいんだけど誰か pdf にしてうぷしてYO!
110 :
デフォルトの名無しさん :02/03/23 16:30
>>105 restはschemeにはないよ。cdrにしたら?
>>108 > (length (1 2 3 4))
quote付いてないよ
>>110 >>BASICER
>> (length (1 2 3 4))
>quote付いてないよ
う、初歩的しょぼいミスー。すまぬ
(length '(1 2 3 4))だね
112 :
BASICAR :02/03/23 18:24
> (length '(1 2 3 4)) quote: misused: '(1 2 3 4) is not a symbol > 出鼻でつまづいたのはDrSchemeが始めてだす〜
113 :
BASICAR :02/03/23 19:30
もう嫌になりました。 DrSchemeはアンインストールします。 皆さんありがとうございました。
114 :
デフォルトの名無しさん :02/03/23 19:39
DrScheme version 103p1で動いたよ
(define (mylength l)
(cond
((empty? l) 0)
(#t (+ 1 (length (cdr l))))
)
)
(mylength (list 1 2 3 4))
lengthは駄目だって。予約済みだから。
>> (length '(1 2 3 4))
>quote: misused: '(1 2 3 4) is not a symbol
このエラーはねー 「リストと quote 」
ttp://www.edu.cs.kobe-u.ac.jp/Enshu6/2000/scheme_web/sexpr_quote.html みてみそ。
ただしBiggner modeじゃないとStepperは使えない
115 :
デフォルトの名無しさん :02/03/23 19:46
DrSchemeは、なんであんなアホなモードがデフォなんでしょ?
116 :
デフォルトの名無しさん :02/03/23 23:30
procedure をカタカナにすると「プロシージャ」なの? 英語発音とずいぶんずれてるような気がするけど。
117 :
デフォルトの名無しさん :02/03/23 23:56
フランス語だとポロセドレ
118 :
BASICAR :02/03/24 09:18
SICPって日本語訳は4600円なのに原書は8400円くらいするんですねぇ。
120 :
デフォルトの名無しさん :02/03/24 18:26
なぬ?
web だと読まないんだよね。日本語訳はひどいらしいから英語買ってみようか なぁと。4000円くらいなら買うけど8000円だとためらうなぁ。
>>122 そんなに日本語訳ひどいかなぁ? 少し特徴のある訳し方だとは思うけど、
表面的な意味は十分理解できるよ。
>>123 そうなの?じゃ日本語訳買ってみようかなぁ。原書読破っていうのも楽しそう
だけど。
125 :
デフォルトの名無しさん :02/03/24 22:56
まさにSICPをオンラインで見ながらDrSchemeで勉強始めたものです。 まだ全然なんですが、Schemeって3つ以上の分岐ってどうやるのか疑問。 いわゆるelseifです。 if文の中にif文ネストするのもエラーって言われたし。どうすんでしょ?
cond では? if の中に if 書けるよ。
127 :
デフォルトの名無しさん :02/03/24 23:00
ちなみに、「二つの数字a,bが同符号か異符号か判別する」という問題です(SICPの例題じゃないです)。 自分はしょーがないからこんな風にした。 (define a 10) (define b 0) (define c "hoge") a; 10 b; 5 (set! c (* a b)) c; "c = a * b" ;***** if branch ***** ;1 (if (> c 0) (printf "a and b have the same sign") ) ;2 (if (= c 0) (printf "c is zero") ) ;3 (if (< c 0) (printf "a and b have the different signs") )
128 :
デフォルトの名無しさん :02/03/24 23:03
>126 お、情報ありがとうございます。やってみます。 DrScheme見やすくて素人に優しそうなんですけど、全角だめっぽいのが傷。
(let* ((a 10) (b 0) (c (* a b))) (cond ((> c 0) (display "same sign") (newline)) ((= c 0) (display "c is zero") (newline)) ((< c 0) (display "different sign") (newline)))) 厨房だけど、こんなのとか。 ;; different signs (複数形)なの?わからんけど(汗
130 :
デフォルトの名無しさん :02/03/24 23:11
でけた。condがelseifなんですね。読み返したら1ページまえのSICPに書いてあった・・・ (define a 10) (define b 5) (define c 0) a; 10 b; 5 (set! c (* a b)) c; "c = a * b" ;***** cond branch ***** (cond ((> c 0) (printf "a and b have the same sign")) ((= c 0) (printf "c is zero")) ((< c 0) (printf "a and b have the different signs")) )
>129 ほとんど同じっすね。安心。 >different signs (複数形)なの?わからんけど(汗 いや、コメントは僕も適当なんで読み流してください。同符号ならひとつだから単数形、異符号なら二つだから複数形(笑
132 :
デフォルトの名無しさん :02/03/24 23:19
>>125 あれっ。てもとにあるDrSchemeでできるけど。
condじゃだめなの?
133 :
デフォルトの名無しさん :02/03/24 23:56
培風館のLISP 原書 でlispを勉強してるのですが、 そこにでてくるテイル再帰プログラムというのがいまいちなんですが、 (defun hoge (param1) ;処理 (hoge (param)) という風に再帰呼び出しをするときに余計なことせずに その関数そのものだけを呼び出せばテイル再帰になるという理解でいいんですか? また、テイル再帰にすることにどんな意味があるんですか?
末尾再帰は引数付きgoto文
135 :
デフォルトの名無しさん :02/03/25 01:58
condもいいけどassoc系も用途によっては有効かも
136 :
デフォルトの名無しさん :02/03/25 02:02
>>133 LISPは処理系によってどうなるかわからんけど、
schemeだと
(define (hoge) (hoge))
(hoge)
がふつーに動く。
これは末尾コンテクストという概念で、
シーケンスの最後に関数などの呼び出しがあるなら、
それはただのジャンプに置き換わるって事なんだけど。
137 :
デフォルトの名無しさん :02/03/25 02:04
(define (hoge n) (display n)(hoge (1+ n))) (hoge 1) 12345678... 永遠にカウントアップする関数
何度もこのスレで繰り返されたことだけど、 schemeにはループ制御構文はdoしかない。 それもオプション扱いなんだけど。 言語設計者は末尾再帰をサポートすれば専用のループ構文は 全く必要ない事に気が付いた。
139 :
デフォルトの名無しさん :02/03/25 04:37
>>138 後はif文さえ除去できれば。
非正格言語なら遅延実行でif文も無くせるのに
140 :
デフォルトの名無しさん :02/03/25 07:09
良く知らないけど、パターン使うんでしょ?>139 あれってif文みたいなものじゃないの?
141 :
デフォルトの名無しさん :02/03/25 07:21
>>140 パターンマッチングはただのシンタックスシュガー.
142 :
デフォルトの名無しさん :02/03/25 08:13
>>141 >パターンマッチングはただのシンタックスシュガー.
え、何の?
143 :
141じゃない :02/03/25 09:08
if文case文の構文砂糖じゃない?
if,caseはガードに相当する
>>134 センスいーね〜
正しくは、引数書き換え&goto文 だと思われ。
146 :
デフォルトの名無しさん :02/03/25 12:45
>>145 え?センスいいって。どっかに書いてあったのをそのまま書いただけです(w
僕も実はあんまりわかってないです。はい(汗
処理系はなにがいいのでせうか? 今使ってるのはMeadow, XLispStatですが、Common Lispと微妙に違っているので、 出来るだけ準拠したものがほしいのです。できれば、GUIありで・・・。
gauche (・∀・)イイ!!
150 :
デフォルトの名無しさん :02/03/25 14:03
UNIX に限った話ですが、 guile は #!/usr/bin/gulie の書式が使えるんだけど、 mit-scheme で同じようなことできませんか?
guile は #!/usr/bin/guile ではできなかったような気が...
(eq #\a #\a) は未規定なんだね。 guile と gauche は #t 返したけど。
153 :
デフォルトの名無しさん :02/03/25 18:22
>>152 オブジェクト生成の爆発を避けるために
256バイトとかでテーブル参照でもやってるんでしょう。
gc起動が一番コストがでかいから。
154 :
デフォルトの名無しさん :02/03/25 18:29
256個の文字で固定すれば 属性フラグ+文字で1オブジェクト2〜4バイトとして考えても 最大1024バイト程度のテーブル参照で済むから、 そういうのは積極的にやってると思う。 実際ソース読んで見ないとわからないけども。 でもgaucheは漢字も1文字として解釈するんだよね。
あっ、、eq ぢゃないや(汗
>>153-154 そういうことなんですか、実装のことまでは分からないけど。俺もいつかは
scheme 処理系書くぞ。でも今は scheme 書けるようになるのが先だけど。
過去ログに単語lambdaが長いとあったけど lambda->lm はどうよ? (de list(lm x x))
157 :
デフォルトの名無しさん :02/03/25 19:44
schemaの処理系ねー 継続以外の処理は、すぐにでも作れるけど・・・ みんな、どうな風に作ってるんだろ? (ソースみて勉強しないとねー)
lambda は lambda だから カコ(・∀・)イイ!! のに、とか言ってみるテスト。
>>151 #!/usr/bin/guile だけではできませんが、
#!/usr/bin/guile -s
!#
と書けばできます。
#! から !# までをコメントとする guile 独自の拡張らしい。
>>150 ":"; exec gosh -b $0 "$@"
gauche だけどこれでできたから逝けるかも。-b は batch mode. 後ろの 2つ
は何だか知らないけど多分引数を渡すやつ。shell によっては変えないとだめ
かも。
やっぱ #!/usr/bin/env gosh の方が簡単かも。引数渡せるかは調べてないから調べて判ったら教えてね。
もちっとSICP読み進んでSchemeにも慣れたら 「SICP読む→ウマー」ってスレ立てようかと思ってるんですけど、お前らいかがですか。
scheme教えてスレはホスィ
>>160-161 ":"; exec gosh -b $0 "$@"
こういう sh の書き方は知りませんでした。
#!
しかないと思ってた。
これでできるかも知れません。サンクス!
165 :
デフォルトの名無しさん :02/03/25 23:47
誰か Scheme らしいお題をプリーズ!
でも盛り上がるかどうか。。。
このスレがpart4まで来るぐらいだから、SICP興味ある(or実際読んだ)人は少なくないのでは? オンライン版なら誰でもアクセスできるわけだし。
168 :
デフォルトの名無しさん :02/03/26 01:41
[問題] ある地点を(x,y,z)とあらわせるとする。 x,y,zは符号付整数。 ある地点A,B,C・・・を結ぶためのパイプを設置する事を考える。 パイプのコストはなるべく安くすませたい。 パイプは長さ1に対して、コストL円かかる。 パイプを連結するのにB円かかる。 ひとつの連結パーツで最大6つのパイプを一点で連結する事ができるが、 それぞれのパイプの角度は90*n度でなくてはならない。(nは整数) それから、パイプの方向は(1,0,0),(0,1,0)(0,0,1)のいずれかでなくてはならない。 パイプの配置方法を求めるプログラムを作成せよ。 以上、とある高校の夏休みの宿題。 作ってくれ
169 :
SICP 問題1.5に :02/03/26 02:16
(define (p) (p)) (define (test x y) (if (= x 0) 0 y)) (test 0 (p)) を実行してみると面白いことがわかる、と書いてあるけど、それ以前にこれ実行できないんですけど。。。。 素人目に見ても、1行目の関数定義のところが違ってるように見える。(define (p) (p))の最初のpは関数名に取られるわけだから、「引数のない関数は受付ません」というエラーが出るのも当然な気が・・・ 何か間違ってるのかな?
プロシージャは、必ずしも引数が必要でないことはわかりました。ここは、思い違いしていました。 (define (no-argument) 5);引数なしプロシージャの定義 (no-argument);実行! のような、引数なしのプロシージャもOKなんですな。
あまり沢山アンカーつけるとdatの容量が大きくなるから控えめにね。
誤爆スマソ。。。
だれかreverseをschemeで書いてちょ。
名前付きletで書くのと、内部定義で手続き作ってからその手続きを呼ぶよう な手続きって同じことができる?
>>169 その問題は
評価の仕方が作用順か正規順かで
とまるかとまらないかということ。
>>174 (define (my-reverse s)
(let loop ((s s) (reversed '()))
(if (null? s)
reversed
(loop (cdr s) (cons (car s) reversed)))))
>>177 ありがと。簡単そうだけど書こうと思ったら書けなかった(厨
179 :
腰の曲がったおじいさん :02/03/26 16:05
>>145 > 正しくは、引数書き換え&goto文 だと思われ。
書き換えはatomicに起きます。
>>178 一筋縄でいかないと思ったら、問題を分割すると良いですよ。
reverse みたいに下請けを用意するとか、相互再帰する手続きを作るとか。
偉そうな事いえた器じゃないですけど。
>>161 の方法でも大丈夫なようです。
$gosh -V
Gauche scheme interpreter, version 0.4.10
で、引数を取れることを確認しました。確認したのは、附属していたドキュメン
トのまんまですが ↓ です。
---- ここから
#!/usr/bin/env gosh
(define (main args)
(if (null? args)
(copy-port (current-input-port) (current-output-port))
(for-each (lambda (file)
(call-with-input-file file
(lambda (in)
(copy-port in (current-output-port)))))
args))
0)
---- ここまで
182 :
デフォルトの名無しさん :02/03/26 22:17
>>180 相互再帰って何?
二つの関数がお互い同士を呼び合って、再帰するやつだったっけ?
できればサンプルプログラムを使って教えてください。
(相互再帰って3つ以上の関数同士でも出来るのかな?)
>>182 そうですね。複数個の手続きを通して再帰される場合、相互再帰。
1. 対等な関係にある 2 つの状態を調べる述語を書くとき。
典型的なのは、偶数と奇数を調べるもの。実際には letrec を使うのが
良いかも。
(define (my-even? n)
(if (= n 0)
#t
(my-odd? (- n 1))))
(define (my-odd? n)
(if (= n 0)
#f
(my-even? (- n 1))))
2. 手続き呼出。eval をするためには apply をしなければならないが、
apply をするためには引数を eval しなければならない。
3. S 式の解析。手続き read はデータをひとつ読みますが、
データ → アトムかリスト
リスト → データ、データ、データ...
なので、read とペアになる read_form でも定義して、それらを相互再帰
させます。
他にも色々使えると思いますが、慣れるとスイスイ相互再帰な手続きが
書けるようになります。
要は入れ子のデータ構造を解析・解釈するような場合ですね。 長々とすみません。
187 :
デフォルトの名無しさん :02/03/26 23:45
>>174 (define (foldl bop iv ls)
(if (null? ls)
iv
(foldl bop (bop iv (car ls)) (cdr ls))))
(define (my-reverse ls)
(foldl (lambda (y x) (cons x y)) '() ls))
>>177 しんせつな解説有難うございます。
相互再帰かー。かっこいいなー。
リストと再帰を使いこなせるように精進します。
(zipとか使いこなせると括弧良いねー)
189 :
デフォルトの名無しさん :02/03/27 00:27
>>183 「なんでも再帰」
なんと相互再帰つかうと、関数と状態が1対1対応出来るんですね。
関数型プログラミングのパワー炸裂ですね。
>>188 >括弧良いねー
(((・∀・)))イイ!
「なんでも再帰」の一番最後の count-words の in-paren っていう手続きは おかしくないですか?括弧はネスト可能ってなってるけど括弧ネストしてあっ たらエラーになる。
>開き括弧が出て来たら、閉じ括弧が出て来るまでを 一単語とみなす。但し、 >括弧はネスト可能、つまり、 `abc (def (ghi) jkl) mno' は、`abc', `(def >(ghi) jkl)', `mno' の3単語とみなすんだ。 但しダブルクオートで囲まれた >文字列の中では括弧は機能しないとする。さてどうだ。 (define (count-words) (define (in-word c count) (cond ((eof-object? c) count) ((char-whitespace? c) (in-space (read-char) count)) ((char=? c #\") (in-quote (read-char) (+ count 1))) ((char=? c #\() (in-paren (read-char) (+ count 1))) (else (in-word (read-char) count)))) (define (in-space c count) (cond ((eof-object? c) count) ((char-whitespace? c) (in-space (read-char) count)) ((char=? c #\") (in-quote (read-char) (+ count 1))) ((char=? c #\() (in-paren (read-char) (+ count 1))) (else (in-word (read-char) (+ count 1))))) (define (in-quote c count) (cond ((eof-object? c) (error "EOF in quoted word")) ((char=? c #\") (in-space (read-char) count)) ((char=? c #\\) (read-char) (in-quote (read-char) count)) (else (in-quote (read-char) count)))) (define (in-paren c count) (cond ((eof-object? c) (error "EOF in parenthesis")) ((char=? c #\() (in-paren (read-char) count) (in-paren (read-char) count)) ((char=? c #\)) (in-space (read-char) count)) ((char=? c #\") (in-quote (read-char) count) (in-paren (read-char) count)) (else (in-paren (read-char) count)))) (in-space (read-char) 0))
abc (def (ghi) jkl) mno は3語になるんだけど in-paren が #\) を見つけたときに in-space に跳んでっちゃうからいけない んだと思うんだけどどうですか?
今マ版のLispスレageて来たからそっちにも行ってケロ
マ板つまんない。。。
schemeは入出力が弱いらしいですがお前らどうですか?R5RSにある機能だけで 作ったファイルを消したいときはどうやるんですか?
197 :
デフォルトの名無しさん :02/03/28 03:15
あなたは、Common LispとSchemeどちらを愛してますか?
Ruby!
199 :
デフォルトの名無しさん :02/03/28 03:33
>>198 ここではSchemerとでも名乗ってください
(assert (or schemerp lisperp))
お前らschemeで何して遊んでるんですか?
schemeを作るための勉強をしたいのですが、ソース公開してるシンプル な処理系ってどんなのがあります?
204 :
デフォルトの名無しさん :02/03/29 09:14
>203
SICPの4章
は冗談として、シンプルな処理系としてSECDR-Schemeはどうかな。
SECDマシンという仮想機械にバイトコンパイルして動作する。
あとmini-schemeとか。ソースコード1ファイルで約2500行
当然だけど、継続や末尾再帰もサポート。
どっちも昔niftyのFPLにあったけど、多分Webでも拾えると思う。
Tiny-Schemeはmini-schemeのコードを元に作ってるみたいだし。
Tiny-Scheme
http://tinyscheme.sourceforge.net/
205 :
デフォルトの名無しさん :02/03/29 09:17
>>204 SICPの4章にのってるんですか?今webのやつ3章まで読んでるんですが。4章楽
しみだな。
>>205 ありがとうございます。今から見てみます。
207 :
デフォルトの名無しさん :02/03/29 10:11
>181 > Gauche scheme interpreter, version 0.4.10 えーん。あたらしいのにしようよー。
みんな、僕もっと大きくなったら schemacs を作るよ。待っててね。
211 :
デフォルトの名無しさん :02/03/30 15:30
Guile Emacs 発音するとゲマクス。 カコワルイ
guile emacs って make できない。。。
213 :
デフォルトの名無しさん :02/03/30 16:12
>207 Gauche は今 0.5.2 になってるね。
schemeやってる人って少ないのかねぇ。 厨房増えまくっても嫌だけど。
215 :
デフォルトの名無しさん :02/03/31 01:07
まだマクロを書いたことがない初心者なんですけど, Haskellで言うところのリスト内包表記をマクロで定義することもできるんですかね? たとえば,1..10のうち偶数を取り出すというのをリスト内包表記で表すと [x | x <- [1..10], even x] のように,数学の式と同様に表現できます. 内容は,| 以降の条件をすべて満たしたxの集合を表します. こういうシンタックスシュガーは,Schemerは好まないものですかね?
Haskellっておもろい? ってスレ違いか。
217 :
デフォルトの名無しさん :02/03/31 14:44
The Little Schemerをamazon.co.jpで頼んじゃった まだ全然Schemeを使いこなせてないのにぃ
>>217 お。奇遇だね。俺もたった今注文してきたとこだよ。
俺もschemeまだまだわからないけど。多分あの本ってこれからschemeをやろうっ
ていう人が読むような本なんじゃないかな。
Little Schemerは名著です。
しばしば「Common Lisp は実践的、Scheme はアカデミック」みたいな事が 書かれている文書を見るのですが、何がそう言わしめているのでしょうか。 個人的には、Scheme は十分実践的だと思っています。 Common Lisp ライブラリ関数の膨大さ故でしょうか。
Common Lisp には Allegro CL があるから
222 :
デフォルトの名無しさん :02/04/01 01:32
Chez Schemeはダメなんだろうか.
223 :
デフォルトの名無しさん :02/04/01 03:47
>>220 > 個人的には、Scheme は十分実践的だと思っています。
「個人的」だからじゃないかな?
gaucheを「日常業務の中でのちょっとした処理を行うスクリプトを気軽にScheme で書」くために使わせてもらっています。というか勉強中です。
225 :
デフォルトの名無しさん :02/04/01 19:51
>>220 Common Lisp は remove と delete, reverse と nreverse といったように、
同じ動作で効率を重視した破壊的関数が用意されているあたり実践的なんじゃないかな。
あと、一つの関数でもキーワード引数で
* (remove 2 '(1 2 3 1 2 3))
(1 3 1 3)
* (remove 2 '(1 2 3 1 2 3) :count 1)
(1 3 1 2 3)
* (remove 2 '(1 2 3 1 2 3) :count 1 :from-end t)
(1 2 3 1 3)
* (remove 2 '(1 2 3 1 2 3) :test #'>)
(2 3 2 3)
と使いでがあるあたりも。
>>223 「僕の個人的な意見としては」という意味だったんですが。
それとも「個人的な意見」に留まってしまっているのが原因、と?
>>225 なるほど。他にも &optional のような、一見クリーンでなくても実践的な
仕様がありますね。なにも「Scheme は実践的ではない」という意味で
捉えなくても良いって事でしょうかね。
228 :
デフォルトの名無しさん :02/04/02 07:11
Schemeで質問です。 let/let* と letrec の違いがいまいち理解できてないのですが、 let/let* はclosureが評価された値をバインド letrec はclosureそのものをバインド という理解でいいのでしょうか?
ちがいます。>228
>>228 このスレのPart3(いま見えないけど)にあったvarマクロ使ってるけど、
あれネストが減っていいですよ。
(var a 1
var b 2
var c (+ a b)
c
)
=>3
誰か call/cc で java 風な例外処理できるやつ書いて見せてくれないかなぁ。。 とか逝ってみるテスト
233 :
デフォルトの名無しさん :02/04/03 15:02
>>232 (try
...(throw tag)
catch tag
...
finally
...)
って感じのならあるけど、アプしようと思って、今読み返したら、
結構長かった。
作りは、
・lispのcatch & throwのエミュ
・lispのunwind-protectのエミュ(javaのfinallyに対応)
・(try ... catch ... finally)を許す様に簡単な構文変換
の組み合わせで、
catch/throwはcatchで継続と一緒にタグをグローバルな変数へ登録、
throwでその変数を検索といった感じです。
>>233 call/cc の使い方について、ループからの脱出以外にどんなものがあるかを知
りたいので、
>・lispのcatch & throwのエミュ
だけ良かったら見せてもらえますか?これも長くなりますか?
>>234 (define -*-root-*- '()) ;トップレベルに戻るための環境
(call/cc (lambda (cont)
(set! -*-root-*- cont) ))
(define *exception* '()) ;例外補足用のtag環境リスト
;(catch <tag> . cont)または
;(catch all . cont)または
;(finally . cont)
(define (throw-value tag result)
(let loop ((x *exception*))
(if (pair? x)
(cond
; catch <tag>
((and (eq? (caar x) 'catch) (eq? tag (cadar x)))
(set! *exception* (cdr x))
((cddar x) result))
; catch-all
((and (eq? (caar x) 'catch) (eq? 'all (cadar x)))
(set! *exception* (cdr x))
((cddar x) result))
;finally
((eq? (caar x) 'finally)
((cdar x)) ; finally
(set-cdr! (car x) (lambda())) ; dmy-closure
(loop (cdr x))
)
(else (loop (cdr x)))
)
(begin
(set! *exception* x)
(puts "Cannot throw tag and perform a reset"
(list 'throw-value tag result))
(-*-root-*- result)
))))
;sequenceかどうか (define (sequence? l) (and (pair? l) (pair? (cdr l)))) ;sequenceを置けるthrow (throw tag seq...) (define-macro (throw tag . body) (list 'throw-value tag (if (sequence? body) (cons 'begin body) (car body)))) (define (lisp-catch tag body) (call/cc (lambda (cont) (set! *exception* (cons (cons 'catch (cons tag cont)) *exception*)) (throw-value tag (body))))) (define-macro (catch tag . body) `(lisp-catch ,tag (lambda () ,@body))) (define (call-with-catch tag test catch) (let ((throw? #t)) (let ((result (call/cc (lambda (cont) (set! *exception* (cons (cons 'catch (cons tag cont)) *exception*)) (throw-value tag (prog1 (test) (set! throw? #f))))))) (if throw? (catch result) result)))) (define (unwind-protect test finally) (let ((current *exception*)) (push (cons 'finally finally) *exception*) (let ((r (test))) (set! *exception* current) (finally) r)))
>>236 >(define-macro (catch tag . body)
> `(lisp-catch ,tag (lambda () ,@body)))
(define-macro (catch tag . body)
`(lisp-catch ',tag (lambda () ,@body)))
でした。
239 :
デフォルトの名無しさん :02/04/04 10:48
CommonLispの本、出た?
240 :
デフォルトの名無しさん :02/04/04 12:55
Schemeって最初は継続ってなかったんでしたっけ? だからSICPには載ってな いとかこのスレかどっかで見た覚えがあるんですが。
242 :
デフォルトの名無しさん :02/04/05 11:45
SICPの4章のschemeインタプリタを 継続対応にするにはどうすればいいんですか?
243 :
デフォルトの名無しさん :02/04/06 11:26
GUYの論文よめ
244 :
デフォルトの名無しさん :02/04/06 17:51
λμ計算ってなに? 継続や例外処理が使えるようにλ理論の拡張したものらしいけど・・ 何か参考になる本、Web無い? 誰か教えてー。
245 :
デフォルトの名無しさん :02/04/08 21:25
もしかして既出だったらごめん。
商業的な利用が少ないのもそこら辺が一番のネックなのだろうか。 >ライブラリが貧弱
これって2001年に書かれたんだよね。 schemeについて全く触れられてないけど。。。
>>246 Gauche の開発者の人の訳文だし、このスレの人は結構見てるかも。
Common Lisp への批判は、今日の Java への批判に通じる物があるね。
この文章を書いたた人は Python が好きそう。
Common Lisp について批判しているのは、便利なライブラリが揃っていないのと ハックに使いにくい事みたいだけど、本当ですか?
Common Lispでコードを書き始めると、最後までCommon Lispで仕上げる ことになりがち。他の言語やツールと連携することは、可能ではあっても、 快適にできるというわけではないから。だからハック向きの言語ではない と言って良いと思う。Perl/Python/Rubyは他の言語やツールと連携する のが得意だし、カンタンな処理はごく短いコードで書けるから、ハック向 きの言語だよね。 件のページに書かれているように、今すぐ書いて処理したい仕事では、文 字列処理がその多くを占める。だから強力な文字列ライブラリのある言語 は「実用的」だと言えるよね。Common Lispはそうじゃない。カンタンな フィルタプログラムを書こうと思っても、そんなにカンタンじゃない。 UNIX文化にどっぷりつかっている言語と、OS側の機能を前提としない言語 の違いと言ってもいいかもね。
253 :
デフォルトの名無しさん :02/04/10 16:00
LISPで文字列処理するのって、何かメリットありそう?
254 :
デフォルトの名無しさん :02/04/10 18:44
>>253 文字列処理がLISPでできるというメリット
255 :
デフォルトの名無しさん :02/04/10 18:53
The little Schemer がいまアマゾンから届いた。 かなり変わった構成だな。
正直、 (car "あいうえお")=>\あ とできて嬉しいのかと問いたい。 (cdr "あいうえお")=>"いうえお" うむ。
257 :
デフォルトの名無しさん :02/04/11 15:36
scheme制御構造めちゃくちゃ強力だね。 (call/cc (lambda (break) .... このbreakとか。
>>257 breakくらいならたいていの言語にあるだろうけど。
継続のもっと強力な機能が知りたいな、とか逝ってみるテスト。
259 :
デフォルトの名無しさん :02/04/11 15:53
>>258 いや、このbreakを変数の様に持ち回れるって所は他の言語にはないでしょ?
継続は力なり
継続難しいよぉ
「継続を使えばできるよ」 「マクロでできるよ」 ……こんなのばっかりです、
>263 素晴らしすぎると思うのだが。 初めてEmacs-Lispでマクロの練習したときは、その強力さにオロロイタ。 Schemeとかで「プログラムのためのプログラム」組むのも大事だけど、やっぱエディタのマクロ組むと楽しいと思う。 実用的なマクロができあがるとうれしいもの。
scheme やってから Emacs-Lisp 見たら while にとってもとっても違和感があっ た。 ;; とか言って scheme じゃ算数の問題解くだけしかできないけど(w
>>265 >素晴らしすぎると思うのだが。
そう言いたかったんですよ。ごめぬ。
268 :
デフォルトの名無しさん :02/04/12 01:31
だれかLittle Schemer 読んだ人いる? 漏れは今読んでるぞ。
> Little Schemer That was too easy!:P I've just read a few pages and never opened it again. Well, but it might be true the book sometimes is useful.
270 :
デフォルトの名無しさん :02/04/12 02:36
なんで英語でしゃべってんのか知らんが(w あの本は非常によく考えられて作られてると思うぞ。
>>265 のいってるマクロの意味が違っていると思うのは俺だけ?
言いたいことはわかるが。
あれ・・Little Schemerって英語で読んでるんじゃないの。 Is it true that it is an atom? atom で始まって、答えが Yes, because atom is a string of characters beginning with the letter a. 邦訳はどんな感じですかいね。
未だにamazonから来ないのは,俺が発送料などをケチったからか…
emacs-guile の gauche 版だれか作ってくれないかなぁ、 とか言ってみるテスト。
>>275 うちもまだ来てないよ。半年も先なのか(鬱
279 :
デフォルトの名無しさん :02/04/13 04:55
The little Schemer アマゾンで注文して2週間できたよ。
大学の本屋で買った。>The Little Schemer
EmacsLispプログラミング入門ての買った。 Lispってけっこうおもしれー。 どういう用途があるのかよくわかんないけど・・・
lisp勉強しようと思ったとき、コンパイラってどこにある?
284 :
デフォルトの名無しさん :02/04/13 13:35
emacsをlisp使ってる人は沢山いそうだけど、 逆にemacs以外のエディタでlispプログラミングしてる人いる? おれはそんなの考えられないんだけど。
WindowsのXyzzyとか。一種のCommon-lisp Emacsだけど。
290 :
腰の曲がったおじいさん :02/04/13 16:18
>>287 .sawfishrcを書く程度ならviを。
emacsをlisp知らないで使ってる人は の間違い、ごめん。おれは287.
292 :
デフォルトの名無しさん :02/04/13 19:30
俺の知り合いは、ばりばりのScheme使い&vi使い。 もちろん、Schemeのプログラムもviで書いてる。
とりあえずxyzzy使って勉強してみることにする。 SchemeとLispの違いって何?DelphiとPascalの違いみたいなもん? 外出質問かもしれん
294 :
デフォルトの名無しさん :02/04/13 20:57
LIsp は難しいので教育用としてSchemeが作られたんだよ!
>292 何ゆえにその人物はScheme処理系使わないの?
中途半端に絵がうまい人は、線を何度も引いて全体のバランスをとる。 真に絵がうまい人は、線は一度しか引かない。Scheme の哲学しかり。 と、自分なりに思ってみた。
298 :
腰の曲がったおじいさん :02/04/14 07:47
いや、教育用として良く使われているのは結果。 Actor理論に基づいた(Lisp風の)処理系を作るのが当初の目的。 過去スレ読めば文献ポインタもある。
299 :
デフォルトの名無しさん :02/04/14 09:09
ソースコード公開している Scheme の小規模な処理系を コレクションしています。 mini scheme tiny scheme ki-scheme am-scheme LispMe 他にもあったら教えて下さい。 ki-scheme のソースは日本語で丁寧にコメント書いてあるし、 SJIS が通るので良い感じ。 何れは俺も作ってみたいな、scheme 処理系。
s-lisp
つーかemacsでプログラムを書くなんて俺には耐えられない 俺にはだよ,俺には.
開幕から一度でも 打撃戦ってあったか?
誤 爆
304 :
デフォルトの名無しさん :02/04/14 21:07
Meadow vs xyzzy の壮絶な打撃戦か?
Meadowやxyzzyに火よってはならない! 純正のEmacsを使うのだ!
>>304 [[LK9-herTeMV3]]
<<xyzzy>>に一票!
……は置いといて、
>>293 > DelphiとPascalの違いみたいなもん?
LispとSchemeは「どちらかはもう一方の物を拡張した物」等と言った関係ではないので、違います。
実際の違いについては、
>>294 が一番分かりやすいと思う。
>>294 はただの勘違いだけれど、そんな勘違いを生む程度の違いがあります。
307 :
デフォルトの名無しさん :02/04/14 23:23
ようやくThe Little Schemerを配送したとの通知が. いい加減講義も研究もしなければならないから読む暇無いぞモルァ
308 :
デフォルトの名無しさん :02/04/14 23:24
子供さんに読ませるの?
講義をしなきゃいけないような人間が今頃the little schemerかよ・・・ 教わる学生が不幸すぎる・・・
310 :
デフォルトの名無しさん :02/04/14 23:39
うーん、でも子供向けの本って、 「ママみたいに優しく教えてよ!」ってな感じの プログラミング苦手初心者には、効果的かも。 「プログラミング・マニアみたいな人」ばっかりだと、 この世界も広がらないしねぇー。
311 :
デフォルトの名無しさん :02/04/14 23:51
常にカバンの中に入れておいて、食事の前に読むんだよ。
2時間で全部読むれっ!!!
313 :
デフォルトの名無しさん :02/04/15 00:52
>>312 前書きに、rushするな!って書いてあるだろが!!ちゃんと前書きから読め!!
314 :
デフォルトの名無しさん :02/04/15 00:58
315 :
Symbolics :02/04/15 02:11
>>314 Lisp machineでも売ってるのかとおもったぞ。
316 :
Symbolics :02/04/15 02:16
Lispと Schemeの関係は Unixと BSDの関係みたいな物だな.. original (Lisp/Unix) があって、それが使いやすくて亜種がいっぱい できて、そのうちの分派 (Scheme/BSD) が使いやすかったので そのなかで大きな一派になっている。 で、その一派から originalに吸い上げられた機構 (Static scope/TCP) もあったりして、ぐちゃぐちゃになってると。 我ながら強引な説明だ。
>> 280 部外者でも買えるの? それともダイガクセイを装って買った方がイイ?
>>317 部外者でも買えるYO! 学生割引が使えないだろうけど。
それでも中高生ならアカデミックパックは買える。
319 :
デフォルトの名無しさん :02/04/15 12:19
gauche でランダムな1桁の数を求めたいんですけど。 (sys-srandom (sys-time)) (modulo (sys-random 10)) とやってみたけど始めの1桁がかたよってしまいます。他にいい方法あったら 教えてください。
schemeつかてる人は、無条件でCも使えると思って良いでしょうか。
ごめん。Cは使えない。FORTRANならなんとか。。。
322 :
デフォルトの名無しさん :02/04/15 16:59
>>321 ネタ?
初期のList処理はFortran上で行われていて、
そこからList処理拡張を持つFortranや、Lispが生まれた、とか、
Lispの初期の実装系はFortranで書かれたって、知っているよね?
>>321 は罰として、Fortran-moniterシステム使ってLisp machine作ってくだちい。
みんなLISPはよくつかっとるのかね?
レスつけにくいな
>>328 昔はLispコンパイラーやSchemeの実装にも手を出してたけど、
今はEmacsとWnnの設定の時ぐらいしか使わない。
暇があったら GIMPで遊んでみる事にしよう...。
LISPだけで食ってる奴はいるのか
Scheme メインで食っていきたい。他にも、C と Perl なら使っても良いかな。 あくまで補助として。
333 :
デフォルトの名無しさん :02/04/16 00:39
…なんだか俺が教授扱いになっているくさいが,俺は大学院生. 講義はするじゃなくて受けると言えば良かったのか.失敬.
334 :
デフォルトの名無しさん :02/04/16 00:43
★★★★★★★★★★★★★★★★★★ This space reserved for JELLY STAINS! ★★★★★★★★★★★★★★★★★★
>>323-324 同じく。
俺の予想では Lisp スレで Fortran という単語を見た
>>322 は知識をひけらかしたい欲求にかられたのだろう。
336 :
デフォルトの名無しさん :02/04/16 02:37
>>335 >同じく。
>俺の予想では Lisp スレで Fortran という単語を見た
>
>>322 は知識をひけらかしたい欲求にかられたのだろう。
それはどうかな?
最近このスレ、つまらなくなってきているので、
話題の転換を図ろうとしたんですけどねぇ。
もしかして、学部生レベルを超えた話題は全て、
「知識をひけらかしたい部外者」のレスって思ってませんか?
>>319 擬似乱数の生成法によるけど、手元のmanでrand(2)を見ると
上位ビットを使えと書いてある。
Cならj=1+(rand() % 10)ではなく
j=1+(int) (10.0*rand()/(RAND_MAX+1.0))とやれと。
FORTRANは数値計算しかしないので。。。
LISPは最初はFORTRANで実装されていて、遅かったという話しは読んだことある。
CommonLispの入門書でだったかな?
http://www.jah.ne.jp/~naoyuki/Writings/VScheme1.html を読んでやってみたい気もするが、まずはSchemeを使いこなしたい。
このスレが最近単調なのは同感だけど、歴史談議は興味がない。
リアルタイムで知ってるやつもいないだろうし。
Gauche+xml(rdf)+CGIでいろいろやりたいから、その方面の話題を希望。
#英語はなかなか読み進められないんだよ。。。
はぁ、がんばってね。 #英語はなかなか読み進められないんだよ。。。 #って意味不明
>>337 > それはどうかな?
> 最近このスレ、つまらなくなってきているので、
> 話題の転換を図ろうとしたんですけどねぇ。
へー、そうだったんだ…。変なこと言ってゴメソ。
> もしかして、学部生レベルを超えた話題は全て
とりあえず俺には
>>322 は学部生レベルを超えた話題には見えない。
> 「知識をひけらかしたい部外者」のレスって思ってませんか?
思ってないよ。
>>321-322 の流れが謎すぎたからそう思っただけ。
# つか「部外者」ってなんだ?
というかこのスレは学部生レベル (ってのもよくわからんが)
を超えてるであろう話題がいっぱい出てますが
「お前はただ知識をひけらかしたいだけちゃうんかと」なんて一度も思ってないですよ。
ただひたすら「勉強になるなぁ」と。
# 実際は理解できない話題が多く、あまり勉強になってないかもしれんが…。
342 :
デフォルトの名無しさん :02/04/16 08:46
portの汎用化とかは面白そうなんだけど。 with-in/out系が生きてくるし。
学部生って逝っても、ピンからキリまでいるし。 計算機まわりの知識とかスキルって、 自分でがつがつ食っていくもんだから、 ○○レベルってのはそのへんに置いとこう。 俺みたいに単に興味本位でいじってる人間には 食え「そう」なものがいろいろ落ちてるスレってだけでいいんだけど。 食う、食わないはべつにして。
lisp,schemeがエンプラで普及しない理由が現れてるな。
346 :
デフォルトの名無しさん :02/04/16 15:38
で。。。 ;;; 解3 ;;; 継続の呼び出しでループを実現するひねくれた解 (display (let ((total 0)) (let ((next (call-with-current-continuation (lambda (k) k)))) (let ((num (read))) (if (zero? num) total (begin (set! total (+ total num)) (next next))))))) これを set! なしで書くことできる?解2のやつはできたけど こっちはわかんない。
>345 イイ!
348 :
デフォルトの名無しさん :02/04/16 17:00
>>344 lisp,schemeがエンプラで普及しない理由が現れてるな。
企業では、AI的用途(エキスパート・システム等)でだいぶ前に導入されて、
今は廃れているという罠
#データ・マイニングとか、ナレッジ・エンジニアリング周りにはAIの残党も残っているけど、
#金融/投資といったシビアな分野ではどーでしょ。(Lisp使う使わないって問題じゃないでしょうね)
大昔から、Lispいじりは大学2年の夏休み自由課題と相場が決まっている罠
>348 でも Emacs を使っている人間は Lisp をいじりつづけるという罠
どういう時にLISPが必要になるんだ!? 生活感をまじえつつ教えてくれ
湾岸で戦争したくなったとき
つーか、知らず知らずのうちにLISPの恩恵を受けてると思われ
353 :
デフォルトの名無しさん :02/04/16 19:10
>350 LISPのマクロを使いたいとき
そうだ そのマクロをつかいたいときってどんなとき!?
357 :
デフォルトの名無しさん :02/04/16 20:44
C++など複雑な言語仕様のプログラミング言語を 触っているとき。 でLispなんて単純すぎると嘆き、結局元の言語にもどる罠
単純だからこそ発想力が求められる。一般人には無理だという罠。
自作エディタにLISPインタプリタのっけたいと思ったら 0から自作?
360 :
デフォルトの名無しさん :02/04/16 21:21
このスレの
>>299 のどれかからソース引っ張ってくれば?
361 :
デフォルトの名無しさん :02/04/16 23:45
The Little Schemerが届いた. 本を開いた瞬間仰天した. 子供に読ませるの?というレスがあった理由が分かる気がするよ. この程度の本なら,英語が苦手な友達も気軽に読めそうな気がする. が,名著たるゆえんが見いだせそうにないのだが…
362 :
デフォルトの名無しさん :02/04/16 23:51
>>361 よく読んでみろ!!
めちゃめちゃ作りこまれてるぞ!!
角度とか。
間違った。229 じゃなくて 299 です。
>>359 KI-Scheme が良いんじゃないでしょうか。
コメントが充実していますし、SJIS も使えます。
>>364 336じゃないけどサンクス。
確かにKI-Schemeは読みやすいね。
>>361 再帰をしっかり理解できている人にとっては
不動点演算子とインタープリタの所以外は、簡単すぎるかもしれない。
再帰を知らない人に、再帰を理解させる本だね。
おいらは 「List遊び」で初めて再帰がわかった。 web で調べてもさっぱりだったけど。
>>361 うん、簡単だよねぇ。
2時間で読むれっていったら誰かさんが「急ぐなヨ」とか逝ってたけど、
オレは30分で読んだYO!
>364 まさか本当に >299 がまとめてくれるとは。THX
KI-Scheme って Makefile 修正したら cygwin で make できる?
聞く前にまず自分でやってみろ
>>372 いや普通にmakeしてもできなかったから、修正したらできるのかなと。
自力でMakefileいじったりできないから聞いてみた。
>>358 「自分は一般人とは違う」などと勘違いしてしまう罠
>自力でMakefileいじったりできないから聞いてみた。 はあ?
377 :
デフォルトの名無しさん :02/04/18 17:42
378 :
デフォルトの名無しさん :02/04/18 19:45
Is is true that this is an atom? manko Yes, because manko is a string of characters beginning with the letter a.
しまった、aで始まってなかった
>Is is true that this is an atom? ( ゚д゚)ポカーン
ぐは。 そこもまちがっとった。
もうだめぽ。
383 :
デフォルトの名無しさん :02/04/19 07:32
ちゃんと読んだかぁ?
やっぱscheme最高!
>383 しろーたん萌え (;´Д`)…ハァハァ
(define func (lambda (arg1 arg2) ... (define (func arg1 arg2) ... どっち派? どっちがきれい?
388 :
デフォルトの名無しさん :02/04/19 21:25
>>387 わたしゃ、lambda派
MITスタイルは好きになれない。
>>388 後者はMITスタイルって呼ばれてるんですか?
>>387 後者が好き。打つのも読むのも楽。構文糖は徹底活用すべし。
391 :
デフォルトの名無しさん :02/04/20 18:07
SICP 2nd ed. 届いたage
392 :
デフォルトの名無しさん :02/04/21 00:07
どっち派でもないが、 (define func (lambda (arg1 arg2) ... (define-function (func arg1 arg2) ... と分かれていた方が好き。 (define (func arg1 arg2 . rest) ... これはうまいな、と思うけども。
>>387 どっち派もクソもねーだろ、このホゲ。
(define f(let(...)(lambda(args)...)))
↑みたいに特に理由が無い限り
(define(f args)...)
に決まっておろーが。
394 :
デフォルトの名無しさん :02/04/21 18:29
>>393 まあ、どっちでもいいけど。
Kent dybvigさんの本だとlambdaを使っているね。
λ式に名前をつけるって感じでこっちが好きだけど、
構造と解釈の普及でlambda無し方が今や主流なのかな。
で、SICPがlambda無しで書いてるから「MIT派スタイル」なんだろうか。
396 :
デフォルトの名無しさん :02/04/21 22:51
つーかただの構文糖だろ スタイルもなにもない
じゃあ、SICPスタイルとか、サスマンスタイルとかにしとけ。
398 :
デフォルトの名無しさん :02/04/21 22:55
ループって、 doとnamed-let,letrecどれで書けばいいの?
あ、schemeの事です。
400 :
デフォルトの名無しさん :02/04/21 23:01
つーかさ、再帰で書け
named-letに一票。
ふつーnamed-letだよな。 多分。
named-letはletrecの構文糖なんだっけ?
doは括弧使いすぎ。 読みにくいよ。
405 :
デフォルトの名無しさん :02/04/21 23:19
うるせー、カス
はぁ、なんなの?
407 :
デフォルトの名無しさん :02/04/22 02:20
SRFIって infoになってたりしないかな... つーか、みなさまは SRFIに乗ったライブラリとかを 使ってるんでしょうか??
Little Schemer の不動点演算子の部分は、 (Y Y) Works! A Lecture on the Why of Y ってタイトルで PostScriptファイルが手にはいるよ。
409 :
デフォルトの名無しさん :02/04/23 02:13
あんま関係無いけどさ、PostScriptファイルをWindowsで簡単に見る手段ない? GhostScript入れるとか無しに。
>>409 GhostScript入れるのが一番簡単だと思うが。
411 :
デフォルトの名無しさん :02/04/23 09:29
>>410 このまえいれてみたんだけど、
日本語がうまく表示できなかった。
412 :
デフォルトの名無しさん :02/04/23 11:10
>>412 確かにスレ違いだけど、このスレは論文とかpsファイルの参照って
結構多いから、こういう情報は助かります。
The Seasoned Schemer はどう? 読んでる人少なそうだが。
>>409 Adobe Acrobat 5 買いな (無料の Reader じゃなくて)。
ダブルクリックで PostScript ⇒ PDF に変換してくれるから。
ただし、よく失敗するけど (GhostScript も同じか)。
416 :
デフォルトの名無しさん :02/04/23 12:28
素直に印刷しれ
>>418 「Schemeを作ろう」だって。
難しくてわかんないや。
>>419 それは末尾再帰展開に対応してないので、schemeとは呼べませんな
421 :
デフォルトの名無しさん :02/04/23 22:30
末尾再帰展開に対応してないと、schemeとは呼べないの?
実装が義務。
R5RSにも必須と書いてある。 末尾再帰をサポートしないと、ループ回すうち スタック溢れちゃう。
424 :
デフォルトの名無しさん :02/04/23 22:37
>>423 >スタック溢れちゃう。
常にそうなるとは限らないと思うけど・・・
プログラミング言語としては末尾再帰無いとナンセンスかな?
ちなみに継続 call/ccは必須うなのかな?
425 :
デフォルトの名無しさん :02/04/23 22:44
ピア損の「計算機プログラムの構造と解釈第2版」って糞訳なの?
>>425 前半は気になるところがいっぱいあった。
後半はあまりそう思わなかった。
慣れただけかもしれないし、訳者が違うのかもしれない。
428 :
デフォルトの名無しさん :02/04/24 17:57
pythonは言語標準で継続を取得できるんだっけ? それとも一部の実装で?
誤爆ですか? Lisp Scemeスレですけど。。
430 :
デフォルトの名無しさん :02/04/24 18:46
今頃気づいたけど typo してた。恥カスィ。 Sceme → Scheme
433 :
デフォルトの名無しさん :02/04/24 20:23
rubyにも継続を付けるとかいう話無かった?
ふと思い付いた便利そうな手続き。 (define (boolean x) (if x #t #f))
debian(sid) の ILISP で guile での補完機能が動くようなってる♪ って以前から動いてた? とにかく c-w-c からいっきに call-with-current-continuation 補完されるのは最高。
and?
>>436 and だと boolean value 以外も返しちゃうから駄目なんです。
こんな感じで使えるかな、と。 (define (whitespace? ch) (boolean (memv ch *whitespace-chars*)))
Scheme一般のルールとして#f以外が真とみなされるなら、 あえて#tと#fにそろえる必要もないんでは。
>>439 それは分かるんですが、述語は真偽値を返した方が気持良くないですか?
まぁ、考え方の違いでしょうか。
考え方っつーより趣味じゃん。
442 :
デフォルトの名無しさん :02/04/25 01:20
Cだと真偽値は整数だから、!!x は0/1になって意味があるけどねぇ…
443 :
デフォルトの名無しさん :02/04/25 01:49
(eq? 'a #t) =>? これは#t/#fどっち?
当然 #f。っていうかどういう質問?
445 :
デフォルトの名無しさん :02/04/25 02:37
Package for interacting with LISPs using EMACSes ILISP is a powerful GNU Emacs interface to many dialects of Lisp, including Lucid, Allegro, Harlequin LispWorks, GCL, KCL, AKCL, ECL, IBCL, and CMUCL. Also some Scheme implementations are supported as well as a preliminary version of Xlisp/XlispStat.
447 :
デフォルトの名無しさん :02/04/25 07:50
448 :
デフォルトの名無しさん :02/04/25 09:08
>>444 #f以外は全部#tとみなすんじゃないの?
>>448 それはこういう場合でしょ。
(if 'a 'true 'false)
=> true
450 :
デフォルトの名無しさん :02/04/25 10:14
>>433 付いてる。callcc{}。
新バージョンでは捨てるという話を聞いたような聞かないような。
>>448 #f以外は真として扱うというだけであって、#tとして扱う訳ではありません。
偽:#f
真:#fを除く全てのもの
451 :
デフォルトの名無しさん :02/04/25 12:36
あと、#fとnilと'()はちがうんだよ nilはschemeだとただのシンボル
elisp の t,nil に慣れてたから #t,#f には違和感あったなぁ、最初。 あと set! とかが返り値ないのも。
453 :
デフォルトの名無しさん :02/04/26 10:10
GuileGLが,make中にエラーを返してきたので, おとなしくGauche-glでやってみることにしたり…
Gauche-glって何ができるんだろ。 OpenGLって何だろ。
無限ループの継続を生成してグローバル変数に束縛することってできます?継 続を生成するためには一回その無限ループを評価しないといけないですよね(?) そうするとループから抜けられなくなるから、継続を束縛するところまではで きるけど、その継続を評価してみることはできないってことになりますか? ;; 本に載ってるプログラムをいじって何をしてるのか実験してみたいんですが。
>>455 例えば、まず
(define top (call/cc (lambda (k) k)))
みたいにしてトップレベルへ脱出できるようにしておく。
で、欲しい継続を大域変数に保存したあとに、
top を呼び出してトップレベルに戻る。
抜粋すると
(call/cc (lambda (k) (set! global k) (top #f)))
みたいになる。
SCMのバージョンが5d6になってたよ。
http://www-swiss.ai.mit.edu/%7Ejaffer/SCM.html >Tanel Tammet's Hobbit compiler is now integrated into the SCM distribution.
>Ported SCM to the PLAN9 operating-system.
>Ported SCM to OS/2, IBM VisualAge C++ v3.
>>456 なるほど。ありがとうございます。
勉強になりました。
下のようなコードを実行してみたのですが、
#<subr:"continuation">hoge
*** ERROR: bad procedure: #f
と言われてしまいました。
しばらく悩んでいたのですが、意味が分かりました。
(cc #f) から無限ループが始まることを期待していたのですが、(top #f)のと
ころでトップレベルに戻ってしまうために cc の値が #f になってしまってエ
ラーになっている、という解釈でいいんですよね。
;; 何がやりたいかと言うと、無限ループの継続を実行したら無限ループが始
;; まるだろう、というのを実験してみたかった。
-------------------
(define cc #f)
(define top (call/cc (lambda (k) k)))
(define (loop)
(let f ()
(call/cc (lambda (k) (set! cc k) (top #f)))
(display "hoge")
(newline)
(f)))
(loop)
(display cc)
(cc #f)
------------------
上の #<subr:"continuation">hoge
は (display cc) (cc #f) の出力です。
459 :
デフォルトの名無しさん :02/04/26 17:48
>>458 cc の値は continuation になってるけど、 top の値が #f になってて、
(top #f) が (#f #f) になってエラーが起きているのでは。
(top #f) を (top null?) とでもすると期待どおりになるのでは。
>>458 ごめん。俺がかんちがいしてたみたい。
(define top (call/cc (lambda (k) k)))
のところからして、変だった。
(let () (call/cc (lambda (k) (set! top k))))
で、とりあえず動く。どうしてかは、よく判らん。
くわしい人に聞いて。
他の事しながら書いてるので、まだおかしいかもしれん。
>>459 さんに教えてもらった通り (top #f) を (top null?) にしたら期待通り
になりました。また (top (lambda (a) a)) でも大丈夫でした。
>>460 >(define top (call/cc (lambda (k) k)))
>のところからして、変だった。
これって変なんですか?うまく行きましたけど。
>(let () (call/cc (lambda (k) (set! top k))))
これは
(call/cc (lambda (k) (set! cc k) (top #f)))
この行を書きかえるんですよね。これでもうまく行きました。
うーん、だんだん混乱してきた(汗
462 :
デフォルトの名無しさん :02/04/26 20:19
今現在で一番効率の良いとされてるgcって何?
gc しないことかな。
464 :
デフォルトの名無しさん :02/04/26 23:27
scm on solarisで、 SCM version 5d6, Copyright (C) 1990-1999 Free Software Foundation. ;loading /home/research/lpsb/usr/local/lib/slib/require ;done loading /home/research/lpsb/usr/local/lib/slib/require.scm を実行。 > (+ 1 2) 3 > (+ 1.0 2) ERROR: unbound variable: 1.0 ; in expression: (+ 1.0 2) ; in top level environment. ;STACK TRACE 1; (+ 1.0 2) 実数が使えません・・・。 > (sqrt 4) ERROR: unbound variable: sqrt ; in expression: (sqrt 4) ; in top level environment. ;STACK TRACE 1; (sqrt 4) sqrtがありません・・・。 なんで?
>SCM version 5d6, Copyright (C) 1990-1999 Free Software Foundation. >;loading /home/research/lpsb/usr/local/lib/slib/require >;done loading /home/research/lpsb/usr/local/lib/slib/require.scm 本当にこれしか表示されてないの。 5d5だと > sqrt #<CLOSURE sqrt "/usr/local/lib/scm/Transcen.scm": (z) (#@if (#@real? #@z) (#@if (#@negative? #@z) (make-rectangular 0 ($sqrt (- z))) (#@$sqrt #@z)) (make-polar ($sqrt (magnitude z)) (/ (angle z) 2)))> てなってるから使えないんだろうって気がするけど。 +が知らない。rootで一回実行してみたら。
466 :
デフォルトの名無しさん :02/04/27 09:54
467 :
デフォルトの名無しさん :02/04/27 11:38
schemeは数だけ特別あつかいしてる、ね?
468 :
デフォルトの名無しさん :02/04/27 11:40
というか数値型で表現できる範囲は処理系に依存してる、か?
469 :
デフォルトの名無しさん :02/04/27 11:41
CやVBみたいなinteger,longみたいな区分けをしてないだけか、ま?
470 :
デフォルトの名無しさん :02/04/27 11:43
その割には文字型なんてものもあったりして区分けがいまいち、だ?
471 :
デフォルトの名無しさん :02/04/27 11:46
個人的にはset!/ref/lengthとかは型によらず統一して欲しいだ、ろ?
472 :
デフォルトの名無しさん :02/04/27 11:47
つーかなんでlistにlist-set!/list-refがない、か?
set-c[ad]r! と nth を使えば良いんじゃないかな。
474 :
デフォルトの名無しさん :02/04/27 13:12
list-refはあるじゃん
(define animals '(inu neko buta)) (set! animals (cons 'ushi animals)) これは immutable object を変更することにはならないよね?
476 :
デフォルトの名無しさん :02/04/27 16:20
>>475 環境が更新されるだけ。
この辺理解してない人多いね。
>>476 ありがとう。確認の為に投稿させて頂きました。
478 :
デフォルトの名無しさん :02/04/27 23:30
defineとset!は環境に作用するんだよ 他の関数set-car/cdr! string-set! vector-set!などは オブジェクトに直接作用する
479 :
デフォルトの名無しさん :02/04/28 00:51
あの〜〜、WINDOWSで使えるLispのフリーなコンパイラって何処に あるんでしょう?
イーマックスを入れろ。
481 :
デフォルトの名無しさん :02/04/28 01:41
windows lisp free compilerで検索しろほげ
482 :
デフォルトの名無しさん :02/04/28 02:14
483 :
デフォルトの名無しさん :02/04/28 02:42
へたれ学部生ですが、勉強になります。 ところでCやなんかと連携するとしたら、 みなさんはどういった風にやるのでしょうか? 大まかな感じでもいいので教えてもらえるとうれしいです。
484 :
デフォルトの名無しさん :02/04/28 07:36
>Cやなんかと連携 組みこみって事かな? とりあえずemacsでも触ってみれば?
485 :
デフォルトの名無しさん :02/04/28 08:30
>>479 Petite Chez Scheme がいいよ。
コンパイラじゃないけど、めちゃめちゃ高速
486 :
デフォルトの名無しさん :02/04/28 12:27
487 :
デフォルトの名無しさん :02/04/28 12:31
>>484-487 色々とレスありがとうございました。
自分でもよく分かってないので、要領を得ない質問になってしまい申し訳ございません。
ただ、Cとかの手続き型で書くのは面倒な部分のみをLispやSchemeで書いて、
Cとかで書いたものと組み合わせるとしたらどういった手段があるのかな?と思ったもので。
紹介してもらったものを色々調べさせてもらおうと思います。
489 :
デフォルトの名無しさん :02/04/29 06:29
>>488 例えば始めから予測がつかない処理ってのがあるでしょ。
GUIのイベントハンドリングとか。
こういった処理をいちいちコンパイルして動作確認するのは面倒。
即席なコードどんどん書いていけるから便利だとおもう。
ある程度パターン化ができるならその部分はCとかに直して効率を上げていく。
>>489 は単にインタプリタな言語ならなんでもいいように見えるが…
492 :
デフォルトの名無しさん :02/04/29 12:42
>>490 プロトタイプから常態繊維はちょっと…
>>491 Lisp/Scheme好きなんでしょ、きっと
>>491 他のインタプリタな言語って例えば何?
LISPだとランタイム込みで数十キロ程度で済みそうだけど。
494 :
デフォルトの名無しさん :02/04/29 14:08
schemeはCtrl+Cシグナルで継続吐く様にするだけで プログラムの中断後にいつでも再開ができる。 これはLISPのデバッグモードみたいなのより自由度高い。 メモリーイメージダンプ取るだけで状態の永続化も簡単。 外部リソースとの連携という問題もあるけど。 suspend/resume時にフック関数を呼ぶ様にすればなんとかなる。 これがあると世界が変わるよ。 他の言語でもできる事かもしれないけど。
495 :
デフォルトの名無しさん :02/04/29 14:49
Sexpr>>>>>>>>XML
>>495 文書の本文も文字列 "..." として埋め込むんですか?
あ、そか、Cとschemeを比べた場合、とかいう話ね。
498 :
デフォルトの名無しさん :02/04/29 20:21
Lispでなくちゃあ出来ない ことって、どんなのがありますか?
>>498 Lisp 指向でプログラムを書く事かな。
Debian に乗り換えたので gauche の deb が欲しい、 とかつぶやいてみるテスト。
501 :
デフォルトの名無しさん :02/04/30 01:45
call-with-in/output-fileとかに渡す関数の中で、 その場の継続を取得した後一旦外に脱出して、 後で再開する試みは成功するでしょうか? (define (test) (let ((resume #f)) (call/cc(lambda(suspend) (with-output-to-file "test" (lambda() (call/cc(lambda(cont) (set! resume cont) (suspend))))) ; with (if (not resume) (error "ポートが開けなかった")) ;ファイル'test'に"hello world\n"と出力 (display "hello world")(newline) (resume) )) ; suspend )) ;let def test
>>501 残念ながら処理系依存。
(規格にはないけど)seekできる処理系ならdynamic-windを使って
「with-...から出たらcloseし、resume時にはopenしてseekして状態を復元する」
マクロを自分で書けるかも。
503 :
デフォルトの名無しさん :02/04/30 02:22
まちがえました。正しくは↓ (define (test-open filename) (let ((resume #f)) (call/cc(lambda(suspend) (let ((res (with-output-to-file filename (lambda() (call/cc(lambda(cont) (set! resume cont) (suspend))))) ;call/cc (set! resume (lambda())))) ; with (if res (res 'ok)) ))) ; suspend (if resume (lambda()(resume (call/cc(lambda(c)c)))) #f) )) ;let def test-open (define close (test-open "test")) (display "hello world") (newline) (close) これで通りました。 これが何なのかというと、ネストしまくった階層の継続を取得して 普通のファイルハンドルと同じ様に持ちまれるかどうか、 の実験です。 display〜部をトップレベルで評価し、openで得た継続(ハンドル)で 状態が戻ればネストを気にせずに色々とできそうだなということで。
504 :
デフォルトの名無しさん :02/04/30 02:35
また間違い。これでラスト。
(define (test-open filename)
(let ((resume #f))
(call/cc(lambda(suspend)
(let ((res
(with-output-to-file filename (lambda()
(call/cc(lambda(cont)
(set! resume cont)
(suspend))) ;call/cc
(set! resume (lambda()))
)) ; res
)) ; with
(if res (res 'ok))
) ; let
)) ; suspend
(if resume (lambda()(resume (call/cc(lambda(c)c)))) #f)
)) ;let def test-open
(define test-close (test-open "test"))
(display "hello world")
(newline)
(test-close)
>>502 with系のポートをオープンしっぱなしという前提にすれば
再定義でできそうな気がするんですが。
505 :
デフォルトの名無しさん :02/04/30 05:12
>>502 with〜をdynamic-wind前提で組まれると困ったりしない?
使い勝手を考えると制御用と、後始末(例外)の2つが必要な気がする。
積極的に使う場合>call/cc
506 :
デフォルトの名無しさん :02/04/30 23:38
ネイティブコードにコンパイルするschemeない? 継続の辺りの仕組みが知りたいんだけど。
508 :
デフォルトの名無しさん :02/05/01 02:18
#((dv 0) (dv 1) (dv 2)) で,ベクターの要素には当然関数の計算結果であってほしいけど, 関数を計算しない状態が要素になってしまいます. で,色々試行錯誤した結果, (list->vector `(,(dv 0) ,(dv 1) ,(dv 2))) などというスマートじゃない感じで落ち着いてしまいました. 普通に関数が展開されたベクターを書くにはどのようにすればいいですか?
`#(,(dv 0) ,(dv 1) ,(dv 2)) でいいはずだが。
510 :
デフォルトの名無しさん :02/05/01 04:55
>>508 vectorは自己評価式(数値や文字列と同じ扱い)なので
外部表現#(〜)の読みこみ時に内部の要素が評価されることはありません。
>>509 の様に定数式で無理やり評価するか、
新規に作ったり、
(vector (dv 0) (dv 1) (dv 2))
または、既存のvectorに対して代入します。
(define vec (make-vector 3))
(vector-set! vec 0 (dv 0))
(vector-set! vec 1 (dv 1))
(vector-set! vec 2 (dv 2))
ちなみに
list->vectorは
(define (list->vector vec) (apply vector vec))
こうやって定義できます。
511 :
デフォルトの名無しさん :02/05/01 09:00
>>509-510 真夜中にありがとうございます.
vector-set! は,何となく気持ちが良くないので使用を控えたかったり.
使った方がなにかと楽だし,使わないとならない局面もありますけどね.
512 :
デフォルトの名無しさん :02/05/01 15:35
>>506 Chez Schemeっていう、わりと気合いの入ったネイティブコードコンパイラもあるが、
有料なんだよな…(www.scheme.com。無料版はインタプリタ)
call/ccの実装方法を手軽に知りたかったらどうすればいいんだろうねえ。
もっとも素朴な方法としては、call/ccでsetjmpかつスタックをコピーしておいて、
その継続を適用するときにlongjmpかつスタックを復元すればいいんだけど。
あるいは、あらかじめプログラムの全体をcontinuation passing styleに変換すれば
ほとんど自明だが。
513 :
デフォルトの名無しさん :02/05/01 18:13
>>511 vector-set!のどの辺が気持ち悪いんだよ
514 :
デフォルトの名無しさん :02/05/01 19:50
>>506 >>512 みたいな実装するには、pthread 使えばいいと思うよ。
GCの時は、全てのスレッドを停止するか、あるいはマルチスレッド対応GC用意する必要があるけど。
515 :
デフォルトの名無しさん :02/05/02 03:39
>>506 byte code 方式で継続サポートしてるschemeのソース見たことあるけど(Xscheme)…
いかにもbyte code VMじゃないと実装しにくそうな実装方式を使っていたなあ。
>>514 pthread使うと何がいいの?
スタックをコピーしやすいとか?
517 :
デフォルトの名無しさん :02/05/02 09:01
>>516 結論急いではまってしまった…
>>512 スタックのコピーなら、とりあえずUNIXのfork()と共有メモリかもねー。
ところで、例の仕様書(R5...)は、
そういう仕様(スタック・コピーによる呼び出し元への戻りの保障)
を要求しているの?
518 :
デフォルトの名無しさん :02/05/02 10:01
>>517 fork()したらset!の結果が共有できなくて困ると思うが…
だいいちコピーするのがスタックだけじゃすまない。
あ、ヒープはmmapしとくとか?
>ところで、例の仕様書(R5...)は、
>そういう仕様(スタック・コピーによる呼び出し元への戻りの保障)
>を要求しているの?
昔から、継続作ったらスタックはコピーせざるを得ない。
だって、何度でも呼び出せるんだから壊しちゃいけない。
継続作った時点でコピーするか、呼び出す時点でコピーするか。
519 :
デフォルトの名無しさん :02/05/02 10:44
>>518 mini-schemeは継続をヒープに持ってるんだけど、この方法だと
コピーが一切必要ない。
ただし、実行と共にヒープにオブジェクトをバンバン作りつづける
仕様だからgcの呼び出し回数がやたらと多くなり、そのせいで遅くなる。
(参照切らない限りgcで回収されないという仕組みを利用してる。)
この方法でもある程度は*gcによらない回収*でgcの起動回数を減らす
ことができるけどね。
それでもスピードはちゃんとコピーして別管理する処理系には及ばない。
520 :
デフォルトの名無しさん :02/05/02 10:53
Tiny-Schemeという処理系があるけど、コアはmini-schemeを まるっきりそのまま使ってる。上と同様の理由で遅い。 安全にvectorオブジェクトのネスト構造が使えないのもマイナス。 (gcソース参照。ネスト深いと死ぬ可能性あり。) 組み込み用途としてはスタックレスschemeの方がいいんだけど。
>>519 うん。コピーしなくても要は上書きしなけりゃいいわけなんだが。
必ず新たに作るのは、まあコピーより遅いよね。
で、
>>512 はCにコンパイルするには...という話じゃないの?
522 :
デフォルトの名無しさん :02/05/02 11:13
>>521 「Scheme compilerは」Cにcompileする処理系で、
Cのcontrol stackとSchemeのcontrol stackを共通にしているのってありますか?
Interpreterの実装が無理だと思うんだけど。
C--とcompilerのみの言語/処理系、という組合わせならありそうだけども。
Scheme→Cへのコンパイラを作って、 インタプリタをそのSchemeで書けば良いんじゃないの?
524 :
デフォルトの名無しさん :02/05/02 12:45
525 :
デフォルトの名無しさん :02/05/02 13:41
>>524 本体が1600行ってことはmini-schemeより小さいね。
526 :
デフォルトの名無しさん :02/05/02 13:41
>>518 遅レスですが,,,
ヒープの内容は、共有メモリ上に置いとけばええんでないの?
いずれにせよ、ネイティブコードで継続実装する場合、
fork() か thread使わなきゃ、
言語システムと プロセス管理の混合物作んなきゃなんないから、面倒そうだね。
Windowsのスレッドに対応する場合って、 CriticalSectionの切り替えでできるかな? オブジェクト生成や環境へのアクセス毎に呼ばなきゃいけないから 効率は悪そうだけど、UNIXのプロセスベースよりはまし?
528 :
デフォルトの名無しさん :02/05/02 13:48
>>526 継続ってスレッドよりずっと軽くて原始的なものなので、
(少なくとも概念的には式ごとに別々の継続が出来る)
fork()とかpthreadとかの牛刀を持ち出すのはどうなんでしょう。
それに、fork()しちゃったらGCどうします?
>>527 VMで駆動するにしても1実行サイクル毎にCriticalSection呼ぶ
ってのでもいいかもね。ほとんどの場合I/O関係で時間食うわけだから、
I/O扱う処理直前でCriticalSectionをUnlockさせるとか。
>>527 "Critical Section" よくわかんないっすスマソ
UNIXのプロセスは、thread並に軽いと思うけど…
>>528 fork()したらGCどうする(略)
排他して親プロセスで共有メモリをGC または、GC専用プロセスでって、だめ?
スタックコピーが必要だっていうから、
ポータビリティ有る方法考えたつもりだったんだけど、
プロセスよりもスレッドよりも軽い継承っつうのが狙いなら、
自前でスタック管理した方がいいかもね。
>>528 mmapとかでやるんじゃないの?
大変そうだけど。
>>530 スタックのコピーが欲しいってだけなら
SCMとか参考にしてアセンブラでやったほうが良くない?
プロセスベース継続で擬似スレッド作りまくる様な
schemeのコード実行したらプロセスID枯渇するんでない?
だって継承ってスレッド実装するのによく使ってるよ
昔風にいえばコルーチンを1st classにしたやつだもの
pthreadだとsignalマスクとかthread localとか優先度とか
いろいろ持ってるっしょ。
継承使ってバックトラックやるようなプログラムだと、
継承を何万も作ったりするし。
GCについてだけど、ルートであるスタックが全部見えないと
ヒープだけ見えてもGCできない。
>>531 全プロセスのスタックを親がmmapするとか?
535 :
デフォルトの名無しさん :02/05/02 14:26
>>530 >"Critical Section" よくわかんないっすスマソ
Critical Sectionは関数呼び出し程度のコストでスレッド毎の
リソースロックができる機能だったはず。
状態が
o Lock
x unlock
だとして
thread1 ooooxxxxxxxxxxxoooxxo
thread2 xxxxooooxxxxoooxxxxxx
thread2 xxxxxxxxooooxxxxxxoox
oでリソース(環境)へのアクセスしてる最中は、他のスレッドはブロックされる。
このロック機構はプロセス固有なので、
コストはWindowsのロックの中では最小。(だったはず)
VM命令1回ごとに関数呼び出しほどもコストがかかったら VMの実行がヒトケタ遅くなると思はれる。
537 :
デフォルトの名無しさん :02/05/02 14:38
>>536 じゃあどうすればういいんだyo。
1命令毎に環境へアクセスする必要があるわけじゃないけど、
他のスレッドでgc発動されたら、いつのまにか現スレッドで
参照していたオブジェクトが無効になっていた、なんてのじゃ
使い物にならないよ。
538 :
デフォルトの名無しさん :02/05/02 14:43
プリエンティブなスレッド使える他の処理系、例えばJavaなんかはどうしてるの?
gcはスレッドごとに別にやったりしないよ。 普通は全部のスレッドを止める。 他のスレッドとの競合は、Schemeプログラマが排他制御 するんでは?
540 :
デフォルトの名無しさん :02/05/02 14:49
>>539 全部のthreadはどうやって止めるの?
gc発動thread以外のthreadにSuspendThread送るのかな?
いきなり止められたthreadがクリティカルな処理をしてた場合
はどうすんの?
例えばlistを生成中に他のthreadでgcによる停止が起きた場合、
作成中のlistはそのthread以外、どこにも参照されてないから
gc発動後無効objectとなったりしない?
あ、生成中にはロック掛ける必要があるね。 プログラムカウンタ進めたり、計算した結果を数値objectとして 返したりする場合もロックは必要。 ロックしないで可能な事ってかなり限定的なものだと思うけど。
結局、CriticalSectionで環境アクセス毎にロック掛けるのが 一番簡単なんでしょ? 全部のスレッドを止める必要はなく、各スレッドでロック機構を 使用してればどれかのスレッドでgc発動したら自然とブロック されるわけだし。
>>540 例えばバイトコードをinterpretするVMの話で良いよね?
みんなが「せーの」でGCに入るのは、たしかにけっこう難しいんだよ。
だからSunのJVMはなかなかgreen threadからnative threadにできなかった。
例えば、100サイクルに1回グローバルなフラグを見て、立っていたら
スレッド内部の情報を全部GCから見えるところ(スタックとか)に書いて、
「OKだよ」とGCスレッドに言う。そして、GCが終了するまで待つ。
>>541-542 「環境アクセス」って、SchemeやLispだと「変数の読み書き」っていう意味だけど、
それでOK? ローカル変数を読むたびにいちいちロックするの?
オブジェクトの生成は、たとえばスレッドごとに1ぺーじずつ確保して
(ここはロック必要)ページを使い尽くすまではロックしないで良い。
>>544 >ローカル変数を読むたびにいちいちロックするの?
正確に言うと、自分のいるローカルな環境フレームについてです。
駆動部でそれをちゃんとやってれば、schemeコードを作る側のプログラマが
リソースの排他制御を気にする必要は無いってことですよね?
管理外のリソースは別にして。
>オブジェクトの生成は、たとえばスレッドごとに1ぺーじずつ確保して
これができればいいんですが、処理系を始めから複数スレッド前提で作る
ような気合の入った実装をしないといけないですよね・・・・。
>>543 その「待ち」と「移動」コストってどれぐらいなんですかね。
アクセス毎のロックを行うよりはマシなんでしょうか。
いっこずつ試してみたいものですが。
>>545 Schemeプログラムで、複数のスレッドで共有変数やデータを書き換える
なら、排他制御を意識せざるを得ないと思うが。
逆に言うと、Schemeプログラマが陽にロックを指示しない限りVMは
ロックする必要が無い。
>>546 「待ち」はOSが用意したスレッド間の同期プリミティブを使うんだろうね。
GCは短くても数msくらいはかかるだろうから、同期コストは問題にならない
のでは。
VMローカルのデータをGCから見えるところに書くのは、レジスタ変数を
スタックに退避する程度の手間でしょう。
>>547 >データを書き換えるなら、排他制御を意識せざるを得ないと
ああ、おっしゃる通りでした。
駆動部による読み書きが安全であっても論理の上で正しいのか
とは別問題でしたね。となると上位側にもロックは必要ですか。
どうやら協調型スレッドと混同してた様です。
となると任意のタイミングで継続の切り替えが出来るschemeとしては、 プリエンティブにする旨みって、I/Oの部分ぐらいしかない気がする んですけど・・・。 他に実装コストに見合ったメリットってあるでしょうか(おい
551 :
デフォルトの名無しさん :02/05/02 15:57
I/Oだけプリエンティブにするトカ。
552 :
デフォルトの名無しさん :02/05/02 18:48
括弧を見てるとめまいがする
554 :
デフォルトの名無しさん :02/05/02 20:34
schemeでまるちスレッドってどうやるの?
Cなんかで括弧 3つくらいのネスト見ても余裕で読めるようになるとか。
括弧は大気と同じようなものなので、濃すぎ (ネストし過ぎる) と酸素過多に なってよろしくない。Lisp プログラムは字下げで読むべし。
557 :
デフォルトの名無しさん :02/05/03 00:31
>>523 > Scheme→Cへのコンパイラを作って、
> インタプリタをそのSchemeで書けば良いんじゃないの?
そのインタプリタが動く時のcontrol stackじゃなくて、
インタプリタが実行するプログラムの方のcontrol stackです。
対象がインタプリタだろうが何だろうが、コンパイルすれば、
control stackを共通化するのは比較的簡単です。
558 :
デフォルトの名無しさん :02/05/03 00:58
おれの自作schemeインタプリタ、 カウントアップしながら出力するコードでベンチ取ったら、 VisualC++6SP4:10秒 おれscheme:13秒 でした。 結構いい線いってる? (ほとんどコンソールの出力に時間取られてるんだろうけど)
559 :
デフォルトの名無しさん :02/05/03 01:06
やっぱSchemerは自作Schemeを持つべきですかね?
560 :
デフォルトの名無しさん :02/05/03 01:07
10万回のループで、 おれschemeでは5000回に一回ほどgcが起動する割合。 Cのソース #include <stdio.h> #include <time.h> main() { int i; time_t start = clock(); for (i = 0; i < 100000; i++) printf("%d\n",i); printf("interval %d\n",clock() - start); } Cのコンパイルオプション cl /O2 /GB /Og /GA /Ob2 /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD test1.c schemeのソース (define (call-with-time expr) (let ((starttime (clock))) (unwind-protect (lambda () (expr)) (lambda () (display* "interval " (- (clock) starttime) (newline))) ))) (define-macro (wt . body) `(call-with-time (lambda () ,@body)) (define-macro (donum var s e inc . body) (let ((loop (gensym))(comp (gensym))) `(let ((,comp (if (<= ,s ,e) < >))) (let ,loop ((,var ,s)) (if (,comp ,var ,e) (begin ,(cons 'begin body) (,loop (+ ,var ,inc))) ,var))))) (wt(donum i 0 100000 1 (display i)(newline)))
>>559 自作しろとは言わないけど、隅々まで知ってる処理系
持ってるにこしたことない、とは思う。
562 :
デフォルトの名無しさん :02/05/03 02:06
563 :
デフォルトの名無しさん :02/05/03 04:05
>>557 >
>>523 >> Scheme→Cへのコンパイラを作って、
>> インタプリタをそのSchemeで書けば良いんじゃないの?
>
>そのインタプリタが動く時のcontrol stackじゃなくて、
>インタプリタが実行するプログラムの方のcontrol stackです。
>
>対象がインタプリタだろうが何だろうが、コンパイルすれば、
>control stackを共通化するのは比較的簡単です。
? 意味が分からない。
共通化できたんなら良いのでは。
誤解してると逝けないので言い直すと、
「まずコンパイラを作る。
インタプリタはそのコンパイラを使って『すなおーに』実装する。
(define (eval exp env) ...)と言うように。
(インタプリタからコンパイルされたprocedureを呼び出す
プリミティブだけはCで用意しておく。)
その結果、インタプリタとコンパイラで実行環境が全く共通の
処理系ができる。」
つまり、インタプリタは自分でスタックを管理したりせずに、
Schemeの関数呼び出しや継続の機能をそのまま使えばよい。
564 :
デフォルトの名無しさん :02/05/03 11:03
>>564 その辺の色々ためしたら全体的に2倍以上遅いことがわかった。
短い夢だったよ。
でもインタプリタとしてはコレ以上速くなるとは正直思えない。
数値演算や配列アクセスも含めて、C++と 2倍くらいしか違わないインタプリタが作 れたなら何かとんでもない大発明をやらか したものと思われる。 ぜひ公開して世界を驚かせてくれたまえ。
へえ、おれはそんな大発明をしたのか? 結構ちょろいね。大発明なんて。 セルの再利用とかキャッシュ組みこんでるだけなんだが。 まあそれなりに苦労はしたけど。 あ、公開は勘弁してくれ((((;´Д` )))))ガクガクブルブル
>>567 どうみてもただの勘違い。
C/C++で書いたインタプリタでC++ネイティブの1/2の性能が
でるわけがない。
足し算1回するのに必要な機械語命令数を考えればわかる。
>>568 まあ、そんな物凄い勢いで否定せんでもいいだろ。
2倍*以上*とかかいてるし。
たぶん特定条件でせまるって事はありえると思うよ。
LinpackでC++の半分出ればマジで大発明だと思うよ。 (行列演算プリミティブを用意するというのはナシで。)
Limpackは面倒だろうから配列の乗算でも試してみたら? (define (make-matrix n v) (make-vector (* n n) v)) (define (mref matrix size x y) (vector-ref matrix (+ (* size x) y))) (define (mset! matrix size x y v) (vector-set! matrix (+ (* size x) y) v)) (define (matrix-* m1 m2 size) (let ((result (make-matrix size 0.0))) (do ((i 0 (+ i 1))) ((>= i size) result) (do ((j 0 (+ j 1))) ((>= j size)) (do ((k 0 (+ k 1)) (sum 0.0 (+ sum (* (mref m1 size i k) (mref m2 size k j))))) ((>= k size) (mset! result size i j sum))))))) (define (mat-bench size) (matrix-* (make-matrix size 1.0) (make-matrix size 1.0) size) #t) (mat-bench 500) mrefやmset!はマクロでも良いよ。 これがCやC++の倍の時間でできる? 手元の処理系だと100倍くらいかかったけど。
CやC++のインタプリタを相手にするなら希望はあるかもしれん。
KI-Scheme なんだけど ApplyFunc の中でクロージャの場合、 SaveEval(EndClosure, evEnv, NIL) でスタックつんでいるから、 真の末尾再帰ではない、というのは正しいでしょうか?
574 :
デフォルトの名無しさん :02/05/05 02:39
末尾からの無限呼び出しでオーバーフローするか試したらどうだ?
575 :
デフォルトの名無しさん :02/05/05 02:44
C言語の enum {A,B,C,D}; switch (type) { case A:return B; case B:return C; case C:return D; case D:return A; } みたいな比較を schemeで簡潔にやるとしたらどうなるんですか? (define A 0) (define B 1) (define C 2) (define D 3) (case type ((A)B) ((B)C) ((C)D) ((D)A)) とやると、シンボルの比較になってしまう様ですが。 (cond ((= type A)B) ((= type B)C) ((= type C)D) ((= type D)A)) とするしかないでしょうか。
Cだと名前を使いたくても数値になっちゃうわけだが、 Lispだとシンボルのまま使えて便利じゃん!
わざわざ数値という表現に落す必要があるのかと小一時間…
DOS版のバイナリダウンロードして試してみたら、 Error: foo : insufficient memory となったよ。 やっぱり、minischeme のようにスタック積む時は、 つねに環境も一緒につんだ方がいいのかね。 そんで、スタック戻すときに環境も戻す。
580 :
デフォルトの名無しさん :02/05/05 10:31
>>563 > つまり、インタプリタは自分でスタックを管理したりせずに、
> Schemeの関数呼び出しや継続の機能をそのまま使えばよい。
インタプリタの実行するプログラムは動的に変わるから無理。
> (define (eval exp env) ...)と言うように。
> (インタプリタからコンパイルされたprocedureを呼び出す
> プリミティブだけはCで用意しておく。)
> その結果、インタプリタとコンパイラで実行環境が全く共通の
> 処理系ができる。」
「実行環境」って何の事言ってるの?
envはどうやって実装するの?
>インタプリタの実行するプログラムは動的に変わるから無理。 ハァ? >「実行環境」って何の事言ってるの? 制御スタック。それを共通化したかったんじゃないの? >envはどうやって実装するの? alistでいいんじゃない? 凝った事したければcasual shallow bindingとか使っても 良いけどさ。
もっと具体的に言ってみる。 ・applyは組み込み関数として用意しとく。 ・evalはSchemeで書く。 例えばifの処理は (eval (if 式1 式2) env) ≡ (if (eval 式1 env) (eval 式2 env)) (eval (if 式1 式2 式3) env) ≡ (if (eval 式1 env) (eval 式2 env) (eval 式3 env)) となるようにすれば良い。 λ式を評価するときは、 (eval λ式 env) ≡ (lambda args (eval λ式の本体 (extend-env λ式の引数部 args env))) とする。 (≡の右辺はコンパイルされてprocedureになることに注意。) (eval (関数 . 実引数) env) ≡ (apply (eval 関数 env) (eval-list 実引数 env)) としてしまえば良い。 ・あとはread-eval-printループを書く。 これだけでtail-recursiveなインタプリタができるし call/ccの処理もできるだろ?インタプリタ用の実行時 スタックなんて陽に用いる必要はない。 (こんなの、よくある手法だと思うが。)
583 :
デフォルトの名無しさん :02/05/05 12:13
>>582 > インタプリタ用の実行時
> スタックなんて陽に用いる必要はない。
> (こんなの、よくある手法だと思うが。)
必要があるかどうかじゃなくて、
もともと継続をforkやthreadでという話からの流れで、
そんなことやっている実装はないんじゃないの、と言う話をしているんです。
あなたの例では、インタープリットされるプログラムのコントロールスタックは、
インタープリター自身の局所変数ですね。Lisp 1.5と同じ。
> 制御スタック。それを共通化したかったんじゃないの?
全然一緒になってないよ。
継続を実装する時に、「制御」について別の扱いしないといけないでしょ。
>>583 >あなたの例では、インタープリットされるプログラムのコントロールスタックは、
>インタープリター自身の局所変数ですね。Lisp 1.5と同じ。
コントロールスタックという言葉の意味が分かっているか?
上のインタプリタのコードで、環境はenvというインタプリタの
変数として陽に表されているが、コントロールスタックはコードの
どこにも出てきていない。(コンパイラの実現する機能をそのまま
使っている。)
>全然一緒になってないよ。
>継続を実装する時に、「制御」について別の扱いしないといけないでしょ。
やっぱり全然分かってなかったか。
call/ccという組み込み関数は当然すでに用意してあるわけだろ?
で、それを組み込み関数applyで呼び出すだけでcall/ccはすでに
インタプリタで実現できている。別の扱いなんか必要ない。
理解できなかったらやってみ。
585 :
デフォルトの名無しさん :02/05/05 12:23
Lisp/Schemeで普通に使うリスト処理が重たいから、 ふつ〜、リスト処理を内部的にスタックや配列に置き換える
>>585 インタプリタの話か?
まさかconsが配列処理するってんじゃないだろうな。
コンパイラがある処理系でインタプリタの速度気にしてどうする?
587 :
デフォルトの名無しさん :02/05/05 12:31
昔Cのコードを吐き出すCommonLispコンパイラーの生成コードを見たけど、 インタープリタのプリミティブ呼び出しばっかりでちっとも速そうじゃなかったっけ。 CommonLispでも、型宣言もどき入れれば、Cと等価な使い方ができるコード吐きそうなもんだけど、(経験なし)
588 :
デフォルトの名無しさん :02/05/05 12:32
>>586 consが配列処理になる、はLispMachineの昔から常套手段。
Schemeチップではどーなんでしょうね?
>>588 cdr-codingの事を言ってるならあれはメモリ節約のためで
速度は速くならない(まあGCが減れば速くなるが)。
特にrplacdした時が悲惨。
いずれにせよ巨大マイクロコードの終焉とともに消えた
技術。
>>587 うまく型宣言するとCで書いたのと同じコードが出る場合もある。
KCLレポートにtakの例が載っていたはず。
591 :
デフォルトの名無しさん :02/05/05 12:49
>cdr-codingの事を言ってるならあれはメモリ節約のためで >速度は速くならない LispMachine のマイクロ・コードだとそなの? でも、どこにあるかわからないポインタ辿るのと、 配列の次の要素へアクセスするのと、 ではキャッシュのヒット率が違うと思うけど。
592 :
デフォルトの名無しさん :02/05/05 12:53
>>589 特にrplacdした時が悲惨。
どんなお話でしたっけ?
>>591 コピーGCでも似た効果(リストのセルが連続した番地に並ぶ)
は得られる。
594 :
デフォルトの名無しさん :02/05/05 12:59
コンパイラ・コードで、内部完結する処理だったら、 リストを使わない等価な処理でごまかしてもいいんではないか?と煽ってみる。
>>592 (setq x '(a b c))
(setq y (cdr b))
として、a b cへのポインタが連続して並んだとする。
x→a
y→b
c
(rplacd x 1)
したときに、(b c)を上書きして壊すわけにはいかないので
forwarding pointerという「見えないポインタ(勝手にたどる
ポインタ)」をaの場所にいれ、他にセルを割り当てて、
x→→(a . 1)
y→b
c
としなければならない。nreverseとかやっちゃうと大惨事。
スレ違いっぽいけど、AppleScriptは速度を上げるために リスト処理を内部的には可変長配列で実装し直したという 歴史があったような。
>>596 主に線形のリストしか使わず、書き換えもあまりしないなら
良いかも。挿入は遅くなると思うが。
>>588 Schemeチップはcdr-codingしてないよ。
GCでコンパクションGCはしてたけど。
「次期バージョンではphantom stackを使う」
とストールマンが書いていたが、本当にそういうチップが
作られたかは不明。
599 :
デフォルトの名無しさん :02/05/05 13:42
んで、けきょーく、Schemeコンパイラーにおける継続の効果的実装方法は どないでしょうか?特にネイティブ・コード重視の場合。 >>全然一緒になってないよ。 >>継続を実装する時に、「制御」について別の扱いしないといけないでしょ。 > >やっぱり全然分かってなかったか。 >call/ccという組み込み関数は当然すでに用意してあるわけだろ? >で、それを組み込み関数applyで呼び出すだけでcall/ccはすでに >インタプリタで実現できている。別の扱いなんか必要ない。
popしないスタックを使うとか‥‥‥。 環境や継続を生成しない場合だけスタックフレームを解放して、 それ以外はスタックがどんどん伸びていく?
601 :
デフォルトの名無しさん :02/05/05 14:15
http://www.ccs.neu.edu/home/matthias/Scheme2000/ にある
A portable implementation of first-class continuations for unrestricted interoperability with C in a multithreaded Scheme -- page 65
Marc Feeley, DIRO, Universitat de Montreal, Montreal, Canada
はどうか。上のほうでも誰か言ってたけど、pthreadとか普通のスレッドを利用して
call/ccを実装するっていう。
602 :
デフォルトの名無しさん :02/05/05 14:34
fork()がプロセスのコピーをするように、 走ってるthreadのコピーを作る事って、可能でしょうかね。 もし可能なら、手抜きポータブル継続実装に使えそうですね^^)
この論文の方法だと、(俺が誤解してなければ)「走ってるスレッドのコピーを作る」 必要はないと思ったのだが、理解に自信がなくなってきたので出直してきますsage
世界にはこんなに熱いワークショップがあったのか
>>603 論文斜め読みしました。
こんな感じでしょうか?
・継続を含むSchemeとCの相互運用を実現するために、[KBD98]が提案した
「C threadを使ってポータブルにCのスタック・コピーと実行をする」方法を
Gambit-C という実装系で採用しようと検討している。
並列動作が主目的ではないため、thread切替のオーバー・ヘッド (2ms)が、
すんげー気に入らない。
・C thread (win32, POSIX, SUN LWP)は、
スレッド生成時に、任意のスタックを与える事ができる。
(従って、継続したいスレッドのスタックをコピーして、
新規スレッドに渡せば、継続の繰り返し実行も可能な感じ。
但し、論文ではCの関数は one shot だと言って、
副作用があるから面倒そうな事を言っている。)
あと、言い忘れましたが、
>>603 論文ありがとうございますた。
けきょーく、Scheme コンパイラで継続実装するには、
a. Schemeのローカル変数フレームを、最初からヒープ上に置くか、
b. 実装言語 (Cとか...)のスタック上に混在させておいて、
継続の必要が生じてから、ヒープ上へ移す
ってあたりが、正解っぽいですね。
もっと良い実装もあるかもしれないけど...。
607 :
デフォルトの名無しさん :02/05/05 17:31
>>606 c. 継続が作られた段階で使われているスタックエリアを切り離し、
継続が呼ばれたらそれをアクティブスタックエリアにコピーする、
というのもあり。ChezSchemeがそうしてるんじゃないかと。
Robert Hieb, Kent Dybvig, Carl Bruggeman, "Representing Control
in the Presence of First-Class Continuations", ACM Sigplan Notices,
25(6), June 1990. とかでそれぞれの方法が議論されてる。
>>584 > コントロールスタックという言葉の意味が分かっているか?
> 上のインタプリタのコードで、環境はenvというインタプリタの
> 変数として陽に表されているが、コントロールスタックはコードの
> どこにも出てきていない。(コンパイラの実現する機能をそのまま
> 使っている。)
あの〜、再帰で通訳した場合、
「式」を押さえているpointerがcontrol stackになってるんですよ?
Lisp1.5やSECD machineやInterLispの実装考えれば分かるでしょ?
"ret"でprogram counterにstackから番地戻すんじゃなくて、
再帰から帰ったら、局所変数が押さえてるの。
> call/ccという組み込み関数は当然すでに用意してあるわけだろ?
> で、それを組み込み関数applyで呼び出すだけでcall/ccはすでに
> インタプリタで実現できている。別の扱いなんか必要ない。
ネイティブ・コンパイラの実装の話しているのは理解できているの?
スレの上の方から読み直してみ。(ふぅ)
>>606 そういうことだと思うよ。コンパイラについては。
>>601 pthreadの生成死滅のコストが高いから、
継続の生成死滅が激しいとパフォーマンス悪そうだけど、面白そうね、これ。
>>607 そっすね。
継続作成時にスタックのスナップショットを、ヒープに退避して、
実行用ローカル変数フレームは、常にスタック上に置いた方が、
シンプルそうっすね。
>>608 threadの並列実行機能抜きで、
stack dump/stack undump専用のシステムコールとか、
ポータブルなライブラリがあれば便利っすね。
>あの〜、再帰で通訳した場合、
>「式」を押さえているpointerがcontrol stackになってるんですよ?
>Lisp1.5やSECD machineやInterLispの実装考えれば分かるでしょ?
InterLispは知らんが、他はどれも違う。
なんで式が「control」でLisp1.5の万能関数の
どこに「stack」があるんだよ。
ひょっとしてSECDマシンのSとかCが関係あると思ってる?
C言語の制御スタックに相当するのは当然Dでしょ。
で、俺のやり方で何がまずいかを言ってみろよ。
>"ret"でprogram counterにstackから番地戻すんじゃなくて、
>再帰から帰ったら、局所変数が押さえてるの。
「control」の意味が分かってないと思われ。
再帰から「返る」機能自体を実現するのがcontrol stackだよ。
で、Cでの実装では、そこにコンパイルコードの環境を一緒に
置くかも知れない。そうでないかも知れない。インタプリタを
Schemeで書けばそれはどちらでも気にしなくて良い。
>ネイティブ・コンパイラの実装の話しているのは理解できているの?
>スレの上の方から読み直してみ。(ふぅ)
あんたはそのつもりかも知れんがこの流れのもとは、
522 :デフォルトの名無しさん:02/05/02 11:13
>>521 「Scheme compilerは」Cにcompileする処理系で、
Cのcontrol stackとSchemeのcontrol stackを共通にしているのってありますか?
Interpreterの実装が無理だと思うんだけど。
C--とcompilerのみの言語/処理系、という組合わせならありそうだけども。
だろ。つまり「SchemeからCへのコンパイラがとにかく既に存在する」
場合に、コンパイラ以前か以後かはともかく「どうやってインタプ
リタを実装するか」という疑問に答えただけだ。
612 :
デフォルトの名無しさん :02/05/07 19:23
>>610 まあまあ。
Common Lispだと確かにコンパイラを先に作って、インタプリタを
Lisp-in-Lispとして作ってある処理系が多いよね。Spice LispもZeta Lispも、
S-1 Common Lispもそうだ。CMU Common Lispもそうだったはず。
これらの処理系だと、インタプリタが独自に実行時スタックを持ったりはして
いない。Lisp 1.5はコンパイラの方が後だが、スタックはどうしたんだろうね。
たぶんインタプリタにあわせたコードをコンパイラが出したんじゃないか?
call-with-continuationなんて無いから別に難しくないだろう。
>>612 Schemeでは知らないな〜、知ってる?
614 :
デフォルトの名無しさん :02/05/07 21:08
うーん、MIT Schemeは、 InterLisp風のstacklet list使ってややこしいことやっていたような…
615 :
デフォルトの名無しさん :02/05/08 00:10
616 :
デフォルトの名無しさん :02/05/08 12:37
schemeで文字列処理って 無謀?
617 :
デフォルトの名無しさん :02/05/08 15:06
>>616 一通りはできる。正規表現のライブラリもあるし。流用しやすい
アリモノは、PerlやAwk よりは少なさそうだけど。
>>615 おーっ、面白そうな処理系。クロス・コンパイルして組込みでも
使えるよ、ってのがウリなのか。x86 の 赤帽 7.2 で動いたよ。
適当なコードを作っといて、他の scheme でバイト・コンパイル。
scm> (load "./bit.scm")
scm> (byte-compile "foo.scm" "foo.c")
で、C でコンパイルして、a.out を実行。
gcc foo.c bit.c
./a.out
と、README 通りでいけたけど。
>>617 結果うまく表示できる?
write-charしか出力関数が無いみたいだけど
それもなんだかうまく動かなかった。
(何を出力してもヌル文字しか出て来ない。)
>>617 ありがとうございます。byte-compileうまくいきました。
まだ動かしてはないけど。
(他の処理系から読みこませる発想だとは思わなかった。)
bit.scm自身をコンパイルして動かせるのかな?
byte-compileは通ってしまったけど。
>>618 displayとかの他の出力系はlibrairie.scmに入ってますよ。
bit.scmの中にlibrairie.scmをロードする部分があるんで、
それをパス合わせすれば大丈夫かと。
621 :
デフォルトの名無しさん :02/05/08 20:59
>>620 librairie.scm の write がバグってる。string? のところの名前つき let の中の cond の else のところがループになっていないので、 最初の1文字しか出てこない。
結構問題ありみたいですね。 こっちもbccでコンパイルは通るけど一般保護で落ちるし。
common lisp の例の本は出ましたか?
624 :
デフォルトの名無しさん :02/05/09 21:56
SICPのFull Textを、zipかなんかでまとめてあって それをダウソできるとこってどっかにないの?
psならあった(sicp.ps.gzというファイル名だったような)。 htmlもあった。でもそのうち消えた。
627 :
デフォルトの名無しさん :02/05/10 01:46
ページごと持ってくれば? ふつーのダウソツールでおっけーなんじゃ
628 :
デフォルトの名無しさん :02/05/10 12:00
h t t p : / / w w w .geocities.co.jp/SiliconValley-PaloAlto/7043/
にwgetのスクリプトがあって無事ダウソできました。
>>626 本家にpsでありましたよね。むかし・・・。
629 :
デフォルトの名無しさん :02/05/12 00:32
630 :
高校生の女の子の感覚で、埴輪鶏ってどうよ? :02/05/12 07:51
どーでしょ?>>形態素解析 Lisp Schemeからは外れるけど、 オープン・ソースの検索エンジン「Namazu」って結構普及しているよね。 # MS Index Server / Contents Index って結構アレだし。 んで、その検索エンジンは、膠着語である日本語の文節を分割する目的で、 形態素解析エンジン(NAMAZUの場合JUMAN,茶筅)を使ってるよ。
最近あんまり話題にもならない日本語かな漢字変換プログラム でも、 かな文の文節を区切る目的で、形態素解析エンジン使ってるよね ICOTオープン・ソース・アーカイブへ逝くと、 自然言語処理用の CESPソースがあるけど、 Lispソースはなかったかな?
632 :
デフォルトの名無しさん :02/05/12 15:53
S式をHTMLに変換するやつ作ってみたんだけど どうでしょう。 (define (sexpr->html s) (define (put-tag-with-attr tag) (if (pair? tag) (let loop ((x tag)) (cond ((pair? x) (display (car x)) (if (pair? (cdr x)) (write-char #\space)) (loop (cdr x))) (else))) (display tag))) (define (put-tag-omit-attr tag) (if (pair? tag) (display (car tag)) (display tag))) ;ここから (if (pair? s) (let ((tag (car s))) (write-char #\<) (put-tag-with-attr tag) (write-char #\>) (newline) (if (nlength? 1 (cdr s)) (begin (for-each sexpr->html (cdr s)) (write-char #\<) (write-char #\/) (put-tag-omit-attr tag) (write-char #\>) (newline)))) (display s)))
633 :
デフォルトの名無しさん :02/05/12 15:54
;食わせるS式
(define source
((html "lang=\"ja\"")
(head
((META
"http-equiv=\"Content-Type\" content=\"text/html; charset=Shift_JIS\""))
((link "rev=\"made\" href=\"mailto:
[email protected] \""))
(title "更新履歴"))
(body
(h1 "更新履歴")
(hr)
(p "2002/05/11 Version 1.00")
(ul (li "新規作成") (li "公開")))))
;変換結果
(sexpr->html source)
<html lang="ja">
<head>
<META http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<link rev="made" href="mailto:
[email protected] ">
<title>
更新履歴</title>
</head>
<body>
<h1>
更新履歴</h1>
<hr>
<p>
2002/05/11 Version 1.00</p>
<ul>
<li>
新規作成</li>
<li>
公開</li>
</ul>
</body>
</html>
634 :
デフォルトの名無しさん :02/05/12 15:58
・仕様 タグの中に属性がある場合は、タグ名の部分をリストにして、 そのリストにタグ名と属性を入れる。 <html lang="ja">ほげほげ</html> の場合、((html "lang=\"ja\"") ほげほげ)
635 :
デフォルトの名無しさん :02/05/12 15:59
出力される結果はwith-output-to-fileなどで取りこんでください。
636 :
デフォルトの名無しさん :02/05/12 16:01
書き忘れた雑関数 ;リストlが長さn以上ならば#t (define (nlength? n l) (pair? (list-tail l (- n 1))))
637 :
デフォルトの名無しさん :02/05/12 19:22
638 :
デフォルトの名無しさん :02/05/12 20:44
>>634 キーワード付き引数の方が、より直感的でない?
html->sexprを作らないと実用にはならないっぽいですね。
こっちは非常に面倒そうですが。(トークンの切り分けや省略タグの扱いとか)
>>637 うーん、ソース見たら結構大きいんですけど、
もうちょっとコンパクトなやつないですか?
>>638 キーワード付き引数とは?
(html (@ (lang "ja"))ほげほげ) ;@が属性
みたいな感じでしょうか。
640 :
デフォルトの名無しさん :02/05/12 23:32
641 :
デフォルトの名無しさん :02/05/12 23:47
>html->sexprを作らないと実用にはならないっぽいですね。 既存のHTMLソース読みこませないと問題点がはっきりしないと思う。
642 :
デフォルトの名無しさん :02/05/13 01:09
>>641 HTMLの場合、省略可能タグのせいで、ただのタグの切り分け
だけではどうしようもない問題がある。
単に、
<body>
<h1>
更新履歴</h1>
<hr>
<p>
2002/05/11 Version 1.00</p>
</body>
というデータを何も考えずにパースすると、
(body (h1 "更新履歴") (hr (p "2002/05/11 Version 1.00")))
となり、間違った構造になる。
hrやbrなどは例外的に処理しないと駄目っぽい。
643 :
デフォルトの名無しさん :02/05/13 02:57
>>642 そうだね。
あとは<B></B>なんかの範囲タグは中身が無くても省略できなかったりするから、
その辺を別途切り分けできれば結構使える様になると思う。
もっと単純にしようよ。
HTML文書 ::= (ノード...)
ノード ::= (タグ 属性リスト ノード...) | 文字列
タグ ::= シンボル
属性リスト ::= ((属性名 . 属性値) ...)
属性名 ::= シンボル
属性値 ::= 文字列
(define source
'(html ((lang . "ja"))
(head ()
(meta ((http-equiv . "Content-Type")
(content . "text/html; charset=Shift_JIS""))
(link ((rev . "made") (href . "mailto:
[email protected] ")))
(title () "更新履歴")))
(body ()
(h1 () "更新履歴")
(hr ())
(p () "2002/05/11 Version 1.00")
(ul () (li "新規作成") (li "公開")))))
(define (sexpr->html node) (if (string? node) (display node) (let ((tag-name (symbol->string (car node)))) (newline) (display (string-append "<" (car node))) (for-each (lambda (pair) (display " ") (display (car pair)) (display "=") (write (cdr pair))) (cadr node)) (display ">") (for-each sexpr->html (cddr node)) (newline) (display (string-append "</" (car node) ">")))))
646 :
デフォルトの名無しさん :02/05/13 05:13
>>645 短くなったね。
属性は
(meta ("http-equiv=\"Content-Type\"" "content=\"text/html; charset=Shift_JIS\""))
程度でもいいとおもうけど。なんか真面目に切り分けしても無駄っぽいし。
あとは属性無し、中身無しのタグは(hr)(br)の様にするとか。
これがXMLだとcase-sensitiveな問題とか出てくるんだろうな。
html->sexprが待たれるところだけど、こっちはほんとに面倒そう。
html->sexpr まだ中途半端ですが、一応それなりの動作をするものができました。 (html->sexpr "HTMLファイル名") とするとS式が出てくる筈です。 ただし、タグと属性は1つの文字列になります。 2ちゃんのログを読みこませても大丈夫な様です。 各自でpretty-printしてください。 長いのでこうしました。 (define (substring? key d . opt) (let ((pos (if (pair? opt) (car opt) 0)) (dlen (if (and (pair? opt) (pair? (cdr opt))) (cadr opt) (string-length d)))) (and (<= (string-length key) dlen) (let loop ((i pos) (match 0)) (cond ((= match (string-length key)) (- i match)) ((< i dlen) (if (char=? (string-ref key match) (string-ref d i)) (loop (+ i 1) (+ match 1)) (loop (+ (- i match) 1) 0))) (else #f)))))) (define (first-token s) (if (string? s) (let ((pos (substring? " " s))) (if pos (substring s 0 pos) s)) s))
(define (html->sexpr fn) (define (read-token endc) (let loop ((c (read-char)) (r '())) (if (or (eof-object? c) (char=? c endc)) (list->string (reverse r)) (loop (read-char) (cons c r))))) (with-input-from-file fn (lambda () (let loop ((c(read-char)) (stack '())) (cond ((eof-object? c) (if (pair? stack) (car stack) stack)) ((char=? c #\<) (let ((tag (read-token #\>))) (if (char=? #\/ (string-ref tag 0)) (let* ((x (substring tag 1)) (v (find (lambda (s) (if (string-ci=? (first-token x) (first-token (car s))) (car s) #f)) stack))) (if v (let loop1 ((stack stack) (r '())) (if (not (eq? v (caar stack))) (loop1 (cdr stack) (cons (cons (caar stack) (cdar stack)) r)) (begin (set-cdr! (car stack) (append (cdar stack) r)) (if (pair? (cdr stack)) (begin (set-cdr! (cadr stack) (append (cdadr stack) (list (car stack)))) (loop (read-char) (cdr stack))) (loop (read-char) stack))))) (begin (stdout-puts "警告:" tag "は対応関係が異常です") (loop (read-char) stack)))) (begin (if (memv (first-token tag) *omit-tag-list*) (begin (set-cdr! (car stack) (append (cdar stack) (list (list tag)))) (loop (read-char) stack)) (loop (read-char) (cons (list tag) stack))))))) (else (let ((s (string-append (string c) (read-token #\<)))) (if (pair? stack) (set-cdr! (car stack) (append (cdar stack) (list s))) (stdout-puts "警告:" s "はばどのタグにも所属してません")) (let ((xc (peek-char))) (if (eof-object? xc) (loop xc stack) (loop #\< stack )))))))))) stdout-putsは強制的に標準出力などに吐くputsです。 (with-input-to-fileを使用してるので) putsは最後に改行するdisplay*です。 display*は引数リスト全てにdisplayを適用する関数です。
これで最後 (define *omit-tag-list* '("br" "BR" "hr" "HR" "meta" "META" "input" "INPUT"))
>>649 本来なら「今はliの中だから、来て良いタグはこれとこれ」という
文脈情報を使って、<p>や閉じてない<li>を処理するんだろうね。
この辺をデータ駆動にしてきちんとやるとSGMLパーザになっちゃう。
難しさは、
SGML parser >> validating XML parser >> non-validating XML parser
だから、右から作っていかない? XHTML目標で。
>>648 で変換したS式からAタグのHREFを抜き出す関数。
(define (get-href s)
(define (proc x)
(if (string-ci=? (first-token x) "A")
(let ((pos (substring-ci? "href" x)))
(if pos
(puts (substring x pos))))))
(define (seq x)
(if (pair? x)
(cond
((pair? (car x))
(begin (seq (car x)) (for-each seq (cdr x))))
((string? (car x)) (proc (car x)) (for-each seq (cdr x)))
(else (for-each seq (cdr x)) ))
#t))
(seq s))
>>642 その辺は一応考えてみました。(*omit-tag-list*参照)
ただ、こちらの思いこみで処理を書いてる可能性が多々有るので、
あれで全てうまくいくかどうかは判りません。
それと、HTMLのコメントを考慮して無かったので、<!-->〜などはネスト
してしまいます。ブラウザはそんな出力も一応読みこんでくれてますが。
>>644 そういう風に単純化できるとは思いつきませんでした。
現在、タグと属性の分割方法を検討してます。
(できればhtml->sexprも短くして欲しい・・・)
>>650 あんまり厳密にやろうとすると工数ばっかり掛かる(割にあまり面白くなさそうな)
んで、とりあえず今回はこれにちゃんとしたタグと属性を付ける所までを目指します。
ところで、
>SGML parser >> validating XML parser >> non-validating XML parser
HTMLはどこに当てはまるんでしょうか?
思ったより素のschemeで文字列処理をするのはしんどいです。
特に、文字をlistで溜め込んだり、substringで新しい文字列を作って抜き出す
事に抵抗を感じたりします。(直接オフセットが使えないもどかしさ、等)
Guileは共有文字列とかいうのでこの辺のコストを軽減できるみたいですが、
良さそうな方法は無いでしょうか。
653 :
デフォルトの名無しさん :02/05/13 22:40
文字列バッファに溜め込んで最後にsubstringする方法と、 char-listを作って、最後にreverse & list->string どっちがいいんだろうねえ
そんなチュウニングは、まともなものが出来た後でプロファイルしてから考えよ。 何のためのLisp/Scheme, GCか? 考えずにGC任せもまたよし。
655 :
デフォルトの名無しさん :02/05/13 22:58
LISPだと自己投影プログラムが作れると聞きますが、 プログラムが正しいかを証明するプログラムを作れますか? プログラムが正しいかを証明するプログラムが正しいかを証明するには プログラムが正しいかを証明するプログラムで正しいかを証明する事で、 プログラムが正しいかを証明するプログラムが正しいかの証明になりますか?
656 :
デフォルトの名無しさん :02/05/13 23:11
>>655 プログラムが正しいかを証明するプログラムが正しいかを証明するには
プログラムが正しいかを証明するプログラムでは役不足だ。
プログラムが正しいかを証明するプログラムが正しいかを証明するプログラム
でないと証明できない。
や く ぶ そ く ?
658 :
デフォルトの名無しさん :02/05/13 23:19
プログラムが正しいかを証明するプログラムを作るには、 プログラムが正しいかを証明するプログラムが正しいかを証明するプログラム を作らないと駄目って事ですか? プログラムが正しいかを証明するプログラムが正しいかを証明するプログラム が正しいかを証明するにはどうしたらいいんですか?
'プログラム'をメタ化すると、実は プログラムが正しいかを証明するプログラム で十分。
660 :
デフォルトの名無しさん :02/05/13 23:32
アキレスと亀の話を思い出したよ。 なんとなく。
Brownの3-Lisp、Reflective Tower、Reflection
「プログラム」の範囲と、「プログラムが正しい」ってのがどう いう意味かによる。これらを定義せんと作れるとも作れないとも 言えん。 例えば、「1階の型付きλ計算のプログラムが任意の引数につい て停止して正しい型の値を返すかどうか」なら判定できる。 「オレが思う通りの結果をちゃんと返すかどうか」なら、「オレ が思う結果」(仕様)をきちんと書いて入力に渡す必要がある。 「任意のSchemeプログラムが、ある引数について停止するかどう か」なら、そういう判定をするプログラムは書けない。
>>652 >>SGML parser >> validating XML parser >> non-validating XML parser
>HTMLはどこに当てはまるんでしょうか?
HTMLの文書型定義をデータとして与えて動くようなものならSGML parserそのもの。
HTML専用にハードコードしてあるなら、validating XMLとどっちが楽だろ?
>>652 >(できればhtml->sexprも短くして欲しい・・・)
考え方だけだけど...
(define (parse-node tag attributes sub-tags)
(let ((subnodes '()))
(case current-token
(tag
(let ((desc (assq token-value dtd)))
(or (null? desc)
(begin
(next-token)
(parse-node (car desc)
(parse-attributes (car desc))
(cdr desc))))))
(close-tag
(if (eq? token-value tag)
(next-token))
`(,tag ,attributes ,(reverse subnodes)))
(text
(set! subnodes (append-text token-value subnodes))))))
ただし、next-tokenは、次のトークンを1つ読み込んで、その種類を
current-tokenに、値をtoken-valueに入れる手続き。
読んだ文字列 current-token token-value
<TAGNAME tag シンボルTAGNAME
> gt 不定
</TAGNAME> close-tag シンボルTAGNAME
= eqsign 不定
" quote 不定
それ以外 text 文字列(空白または区切り記号まで)
変数dtdには、(TAGNAME その中に直接あらわれるTAG名のリスト)
のリストが入っている。
(define dtd '((html head body) (body ul ol p ... ) (ul li) ...))
(append-text string list)
は、リストの先頭が文字列なら、その後ろに空白とstringをappendし、
文字列でなければリストの先頭にstringをconsしたリストを返す。
(parse-attributes tag)は、「attrib1=value1 attrib2=value2 ...>」を
parseして((attrib1 . "value1") (attrib2 . "value2") ...)を返す。
(べつに逆順でも良い。)
ごめん。parse-nodeはループしなきゃだめだった。 (define (parse-node tag attributes sub-tags) (let ((subnodes '())) (letrec ((loop (lambda () (case current-token (tag (let ((desc (assq token-value dtd))) (cond ((null? desc)) ; 知らないタグは無視 ((member token-value sub-tags) ;; 自分の子供 (next-token) (set! subnodes (cons (parse-node (car desc) (parse-attributes (car desc)) (cdr desc))) subnodes)) (else ;; 自分の子供でない ;; 今のノードを暗黙の内に閉じる。 `(,tag ,attributes ,(reverse subnodes)))))) (close-tag (if (eq? token-value tag) ;; 今のノードが閉じた。>を読み飛ばす。 (next-token)) ;; いずれにせよ、今のノードを閉じる。 `(,tag ,attributes ,(reverse subnodes))) (text (set! subnodes (append-text token-value subnodes)) (next-token) (loop)))))) (loop)))) (define (html->sexpr filename) ... (next-token) ; トークンを1つ先読み。(ホントは何かタグが出てくるまで) (parse-node tag ...)) うーん…
Fibonacciの末尾再帰版を本からコピペしてscmでtraceさせたのですが, 普通にCALL, CALL, .... RETURN, RETURN, ... と, 全然末尾再帰されていないように感じたのですが,scmのtraceが変なだけ?
traceの作りを考えれば当然かと。
668 :
デフォルトの名無しさん :02/05/14 12:38
>>648 なにげに十分短いのではないかと。
副作用のある部分をなんとかしたいところだけど。
ワーム製造ソフトを無料で入手出来るサイト知ってたら教えてください
>>655-660 正しいかどうか分からないプログラムから
正しい結果が出力されることを期待してはいけない。
よって、
'プログラムが正しいかを証明するプログラム'が正しいことを、
'プログラムが正しいかを証明するプログラム'によって証明する為には、
前提条件として、
その 'プログラムが正しいかを証明するプログラム' が正しいということが
既に証明されていなければならない。
671 :
デフォルトの名無しさん :02/05/14 20:36
>>501 ですが、やっと汎用的な形になりました。
ネストの深い処理やwith系関数を、後付けで任意のポイントからポイントまで
の区間に適用する機構です。
;骨組み
(define (divide-continueation-prototype proc)
(let ((resume #f)(after #f)(result #f))
(call/cc(lambda(suspend)
(set! result (proc (lambda()
(set! after (call/cc(lambda(cont)
(set! resume cont)
(suspend #t)))) ;call/cc set!
))) ;proc lambda set!
(if after (after #t))
)) ; suspend
(if resume (lambda()(resume (call/cc(lambda(c)c)))result) #f)
)) ;let def
;使用例)任意の区間の出力を文字列として得る
(define (escape-string)
(divide-continueation-prototype (lambda(divide-point)
(with-output-to-string (lambda ()
(divide-point))))))
(define end (escape-string)
(display "出力")
〜
(end)
=>"出力〜"
672 :
デフォルトの名無しさん :02/05/14 22:12
HTMLタグをS式にすると、何のメリットがあるんだ?
673 :
デフォルトの名無しさん :02/05/14 22:28
>>672 (tag)
<tag></tag>
記述量が倍違う。
は冗談として、
そのままLISPリーダーとして活用できたりするとか。
(with-input-from-string
"<begin><display>hello world!<newline></begin>"
html->sexpr)
=>(begin (display "hello world!") (newline))
(eval(with-input-from-string
"<begin><display>hello world!<newline></begin>"
html->sexpr))
hello world!
よし。じゃそろそろ C コンパイラでも作ろうか。
>>672 HTMLがS式になったなら、それでHTMLがパーズできたってことじゃん。
あとはLispで加工できる。
676 :
デフォルトの名無しさん :02/05/14 23:05
677 :
デフォルトの名無しさん :02/05/14 23:32
タグと属性の分割はこんなのでどうでしょうか。
(define (split-quote-string s)
(let loop ((si 0)(i 0)(quote? #f)(r '()))
(if (< i (string-length s))
(cond
((char=? #\" (string-ref s i))
(loop si (+ i 1) (not quote?) r))
((and (not quote?) (memv (string-ref s i) '(#\tab #\space #\newline)))
(loop (+ i 1) (+ i 1) quote? (if (= si i) r (cons (substring s si i) r))))
(else (loop si (+ i 1) quote? r)))
(reverse(if(= si i)r(cons (substring s si i) r))))))
(define (split-tag-string s)
(let ((tag (split-quote-string s)))
(if (nlength? 2 tag)
(cons (string->symbol (car tag)) (cdr tag))
(string->symbol (car tag)))))
>(split-tag-string "A HREF=\"
http://\ " target=\"_blank\"" )
=>(A "HREF=\"
http://\ "" "target=\"_blank\"")
タグだけシンボルにしてみました。
この辺はperlなら数行で出来てしまえるかも
>>677 やっぱ連想listにしないと検索しにくいよ…
680 :
デフォルトの名無しさん :02/05/15 01:34
<pre>〜</pre> という問題が。
あ、中身をそのまま取りこむなら、あのままで問題ないか。
のぶさんの日記より: #1 [misc] XML 最近、みるたび思う。「なんで S 式にせんかった!」 これが、S 式だったら、今ごろ、世の中は Java ではなくて Scheme だったかも。 そっか。 世の中が Perl や Java だったから S 式になんなかったのか。ガクッ。
684 :
デフォルトの名無しさん :02/05/15 01:56
>>679 (("A HREF=\"
http://\ " target=\"_blank\"") ...)
を
(A ((HREF "\"
http://\ "") (target "\"_blank\"")) ...)
に変換するフィルタープログラムを作るというのはどうか。
685 :
デフォルトの名無しさん :02/05/15 02:17
686 :
デフォルトの名無しさん :02/05/15 02:27
>>686 結局S式じゃダメだと気づいて、皆が捨てたからでしょ。
>S式じゃダメだ なにがだめなんですか
691 :
デフォルトの名無しさん :02/05/15 03:11
S式は内部的な処理、 XMLは外部とのやりとりに使えば? XMLはコスト掛かりすぎだよ。 ここで議論するのもアレだな。
693 :
デフォルトの名無しさん :02/05/15 21:15
XMLとS式による開発速度を比べた場合、かなりの差が出そうだけど。
そうだね。XMLの方がはるかに速いだろうね。 なにしろツールやライブラリの蓄積が違う。 いちいち仕様考えながら作ってたんじゃ追い付くわけがない。
695 :
デフォルトの名無しさん :02/05/15 22:25
>いちいち仕様考えながら作ってたんじゃ追い付くわけがない。 考えろよ
697 :
デフォルトの名無しさん :02/05/15 22:44
ステップ数はnに対数的に増加する ってどういう意味?教えて。ください。
あほらし
700げとずざ
>>697 スレ違いだからアルゴリズム総合スレへでも逝った方が良いと思うが、
ひょっとしてSICPの話だったりするのかな?
>>653 こんな感じでしょうか。
(define (string-resize s n)
(if (<= n (string-length s))
(substring s 0 n)
(string-append s (make-string (- n (string-length s))))))
(define (read-token endc)
(let ((s (make-string 128)))
(let loop ((c (read-char))(i 0))
(if (or (eof-object? c) (char=? c endc))
(substring s 0 i)
(begin
(cond ((< i (string-length s)) (string-set! s i c))
(else (set! s (string-resize s (* 2 (string-length s))))
(string-set! s i c)))
(loop (read-char)(+ i 1)))))))
SchemeやLispってのは過去の蓄積を再利用せず 車輪の再発明ばっかりする伝統があるのかな。 なんでDSSSL使わないんだよ?
704 :
デフォルトの名無しさん :02/05/16 00:01
>>703 すいません。使い方わかりません。
どうやって使うんですか?
例をください。
>>703 国際規格になったようなものは使わないという反骨精神なんだろ、きっと。
せっかくSchemeの応用が大っぴらに規格化されたのにね。手をこまねいているうちに
XSLTができて「Schemeはヤパリ洋梨」ということになっちゃった。
なんでここで車輪の再発明の話がでてくるんだ?
707 :
デフォルトの名無しさん :02/05/16 00:06
>>706 今さらSchemeでHTMLパーザ書いたりしてるからでは?
>>707 ちょっとくらい前の発言を読めば?
710 :
デフォルトの名無しさん :02/05/16 00:12
DSSSLやNetscape JavaScript DOMが世の中に出た頃、 SGMLベースの本格的なタグ記述言語が欲しいと思った。 Javaにうつつを抜かしている漏れを差し置いて、 SunとMSはコソーリXMLを作っていた。 今、一部の人々は S式と XMLの関係に夢中になっている。 数年後に結果が出ていればいいなーと、マジで思う。
恨みなんかないよ。むしろSchemeは好きだが、どうして Schemeコミュニティにはこう自殺傾向というか 過去の財産をあっさりすてて一から書き直してはまた崩しての 非建設的なことばかりする傾向があるのかイライラしてるだけ。 XMLの世の中になったってのに「S式使えば何でも解決!」しか 言わない奴もいるし…
712 :
デフォルトの名無しさん :02/05/16 00:16
>>710 創作意欲を摘み取る様な事言うなよ。
君の都合で今さらパーサ書いたらいけないのか?
それはともかく、DSSSLの使い方がわからんので
やさしく説明してくれ。
710じゃなくて709
>>711 オナニーが好きだからです。
sexpにまみれていられるし。
>>711 >過去の財産をあっさりすてて一から書き直してはまた崩しての
そう見えるのはコミュニティが弱小だから、情報が集まり
にくいってのがあると思う。特に日本では。
Variantな処理系が沢山ある割に、
横のつながりが弱いっていうか。
ただDSSSL使えって言われても、わからん奴にはさっぱりだと思うよ。 せめてどうやって使うとか、サンプルソースコードでもなんでも 情報提供してくれれば悪い印象にもならないと思うけど。
717 :
デフォルトの名無しさん :02/05/16 00:38
>>715 LisperもSchemerもみんな独自に処理系を作りたがるから、
伊達を気取りたくなるんだよ。
消えてった処理系は、数知れず。
うぷぷ、
>>718 みたいに、英語サイトのリンク先示すだけで終わるのも
問題のひとつだと思うよ。
721 :
デフォルトの名無しさん :02/05/16 00:52
わかんないやつはDSSSLなんか使わずに一からパーサでも書けや
>>721 あーあ、期待してたのに。
そうやって突き放すから、新規ユーザーも増えないし、
閉鎖的になるんだよ。
>>722 もしかして対話してる相手が1人だけだとでも思ってるのか?
比較的まともっぽいコミュニティがあるのはemacsかな。 エディタで人望を得た。
>>723 なんかそんな感じだったんで。
これ以上書くと、スレの雰囲気が悪くなりそうなんでやめるよ。
Schemeはすきなんだけどね。
>>724 lispで遊ぶのが目的ではなくて、完全に手段としてだからね。
1つの処理系で統合されてるというのもある。
分家はあるけど。
727 :
デフォルトの名無しさん :02/05/16 01:08
だれかCコンパイラ作って
Sexpr vs. XML
730 :
デフォルトの名無しさん :02/05/16 01:29
>728 視認性 Sexpr>>>XML 柔軟度 Sexpr>>>XML 処理系 Sexpr>>>XML 互換性 XML>>>Sexpr 知名度 XML>>>Sexpr 実装難度 XML>>>Sexpr 本の多さ XML>>>Sexpr
>本の多さ XML>>>Sexpr これだよ!LISPも本を沢山出版するんだ! ・・・そして在庫の山
> 実装難度 XML>>>Sexpr 両方作った人いるのかな。 XMLのパーザくらいなら CommonLispの実装作るより ずいぶん簡単だと思うんだが。
>>732 <Sexpr vs. XML
CommonLispとXMLを比較すんなよ
ここのスレ住人は揚げ足取りばっかだな
734 :
デフォルトの名無しさん :02/05/16 01:55
2chの性でしょう
735 :
デフォルトの名無しさん :02/05/16 01:59
(あ、この場合「せい」じゃなくて、「さが」と読みます。)
>>733 じゃ何と比較すんだよ。
実装って何だよ。
頭の硬いひとだね
>>737 (゜Д゜)ハァ?
頭が固いのは今どきS式マンセーとかいってるヤツらだろ。
>>736 S式じゃないの?
ま、なにがなんでもXMLを勝たせたいわけね。
>それだから粘着厨房って呼ばれるんだよ
743 :
デフォルトの名無しさん :02/05/16 02:13
んじゃ 実装の容易さ XML>>>Sexpr ってことで。 〜〜〜〜〜〜〜〜〜〜〜〜 糸冬 了 〜〜〜〜〜〜〜〜〜〜〜〜 これにツッコムやつは粘着厨房。
ところで視認性はどう見てもXMLの方が上なわけだが、
<そんなむきになってXML擁護して何になるんだろう>
746 :
デフォルトの名無しさん :02/05/16 02:17
約1名、変なのがいるみたいね。 XMLはクソ。これ定説。
そんなむきになってLispやScheme語って何になるんだろう…
>>746 禿げ同。
XMLスレの惨状見れば明らか。
そんなムキになって2ちゃんに書き込んで何になるんだろう。
そんなむきになって世界を支配してるXMLから目をそむけてなんになるんだろう
これは、話し合いに失敗したんで、 無言電話掛けるってパターンかな。
753 :
デフォルトの名無しさん :02/05/16 02:23
今夜のお祭りはここですか?
754 :
デフォルトの名無しさん :02/05/16 02:23
まあ、我々SchemerもXMLには逆立してもかなわないことは 潔く認めて次の話題逝こうや。 まず、S式を廃止してXML化するには
XML化するには?
756 :
デフォルトの名無しさん :02/05/16 02:33
・・・(XMLを使うと思考停止する様です。)
754は静かに息を引き取りました ─fin.
(eval 'XML) =>"<クソ>"
>>758 フ゜quoteも評価できないevalって壊れてるよ。
760 :
デフォルトの名無しさん :02/05/16 03:00
だが壊れているのは759の評価器だった 晒しage
良くわかんない。解説して? (eval 'XML) => XML じゃないの?
763 :
デフォルトの名無しさん :02/05/16 03:14
>>762 説明しよう。
(eval 'XML)を評価する段階でまず
eval => <primitive eval>
'XML => (quote XML) => XML
と、なるわけだ。これで全ての引数の評価が終了した。
次の段階で適用(apply)が起き、
XMLはどこかで"クソ"とbind(XML . "クソ")されてるんで、
(apply <procedure eval> XML)
の適用結果は"クソ"と、なるわけだ。
…つまらな〜い。 しかも変だし。 しかもさっきと結果違ってるし。
結局なにも知らないアホだったか
766 :
デフォルトの名無しさん :02/05/16 03:23
>764 SICPでも読んどけ
ヤレヤレだぜ
(「つまらない」はおいといて) 764の言ってることは正しいと思うが? 何とbindされてようが クォートされてるアトムをエバッたら困るし、 "<クソ>"と"クソ"が違ってる。
SICPは初版も2版も読んだけど…
>>768 そうだな。
どうせクソだからどうでもよかったんだが、
XMLは"<クソ>"が正解だ。
773 :
デフォルトの名無しさん :02/05/16 03:30
755=756=757=765=766=767=無知
775 :
デフォルトの名無しさん :02/05/16 03:32
見事な糞スレage
>>774 まー悔しいのはわかるけどサー
間違いを指摘してもらったら感謝するのが
筋ってもんじゃないの?
知ったかぶってごまかすんじゃなくて。
XMLに叩きのめされたS式厨房が毒づいてウサを晴らすスレはここですか?
おっと。こんどは違う角度で責めてきたな。 >間違いを指摘してもらったら感謝するのが ありがとう。 >知ったかぶってごまかすんじゃなくて。 君に言われたくないね(藁
780 :
デフォルトの名無しさん :02/05/16 03:38
わーい祭り再開だー!
XML =>"クソ"
クソ書くな
Schemeのevalは2引数なんだけど… それにapplyの最後の引数はリストじゃないとダメなんだけど…
マダナンカイッテルヨ
>>783 難しいこと言うから厨房が逃げちまったじゃねーかヴォケが!
>>783 schemeとはどこにも書いてないし、
applyは例で書いたんだと思うよ。
んで、そろそろウザイよ?>きみら
Schemeじゃないのにprocedureと呼ぶの? Schemeじゃないのにリストの最初の要素を評価するの? …チッ、またごまかしてやがる。
764の自作自演uzeeee!
粘着だな
無言電話からストーカー行為へと移りましたな
792 :
デフォルトの名無しさん :02/05/16 04:21
■■■■■■■■ 結 論 ■■■■■■■■ 763はただの知ったか消防で、764は神で、XMLはクソじゃありませんでした。 ■■■■■■■■ 終 了 ■■■■■■■■
そのくらいにしとけよ。 どうせまともに答えられないんだから。
自作自演はおわりましたか?
もーね、アホかと。 evalなんて喜んで使う奴はScheme使いとしては三流に 決まってるんだから、問い詰めたってしょうがねえだろ。 XMLは糞だがオマエも糞じゃ。
オマエモナー
つか、みんな痛すぎ。特に
>>763 。
初心者を装った764の手にうかうか載ってどうする。
つかみんなすごい時間にあそんでるね(w オレモナー
みんな必死だったんだな。 (´-`).。oO(……自分の嫌いなもののスレにノコノコあらわれるのは何故だろう……
今日の今日までLIPSだと思っていた折れは何罪でタイーホですか?
まあ、いずれにしても quoteの levelをまちがえてる 764の方がいたいと思うけど。っていうかそれもネタ? 普通 schemerなら evalなんて使わないし。 っていういか、なんで R5RSで入ったの? 消してほしいものだ... compiler makerはどうしてるの?
802 :
デフォルトの名無しさん :02/05/16 19:22
803 :
デフォルトの名無しさん :02/05/16 21:22
html->sexpr/sexpr->htmlですが、 (tag attr-list contents..)の形に直しました。(attrは相変わらず文字列です。) 元HTMLに対しては正確ではないですが、以下の様な可逆変換が可能です。 (with-output-to-file "out.html" (lambda() (sexpr->html (with-input-from-file "read.html" (lambda() (html->sexpr)))))) たまにタグの対応関係が取れない場合があります。 これは元HTMLが正常である場合、バックトラック解析によるまちがい修正で それなりに回避できそうですが、read-charやset!等の副作用関数がむきだし なのでそれを直す必要があります。 以下、全ソース
(define (split-quote-string s) (let loop ((si 0)(i 0)(quote? #f)(r '())) (if (< i (string-length s)) (cond ((char=? #\" (string-ref s i)) (loop si (+ i 1) (not quote?) r)) ((and (not quote?) (memv (string-ref s i) '(#\tab #\space #\newline))) (loop (+ i 1) (+ i 1) quote? (if (= si i) r (cons (substring s si i) r)))) (else (loop si (+ i 1) quote? r))) (reverse(if(= si i)r(cons (substring s si i) r)))))) (define (string-resize s n) (if (<= n (string-length s)) (substring s 0 n) (string-append s (make-string (- n (string-length s)))))) (define (read-token endc . first-char) (let ((s (make-string 128))) (let loop ((c (if (pair? first-char)(car first-char)(read-char)))(i 0)) (if (or (eof-object? c) (char=? c endc)) (substring s 0 i) (begin (if (= i (string-length s)) (set! s (string-resize s (* 2 (string-length s))))) (string-set! s i c) (loop (read-char)(+ i 1))))))) (define (first-token s . opt) (if (pair? opt) (set! opt (car opt)) (set! opt 0)) (if (string? s) (let ((pos (or(substring? " " s opt)(string-length s)))) (if pos (substring s opt pos) s)) s)) (define (split-tag-attr s) (let ((tag (split-quote-string s))) (if (nlength? 2 tag) (list (string->symbol (car tag)) (cdr tag)) (list (string->symbol (car tag)) '())))) (define *omit-tag-symbol-list* '(br hr meta input BR HR META INPUT)) (define *reuire-endtag-list* '("B" "TEXTAREA" "b" "textarea"))
(define (sexpr->html node) (define (require-endtag? node) (or (pair? (cddr node)) (memv (symbol->string(car node)) *reuire-endtag-list*))) (if (pair? node) (let ((tag-name (car node))) (display* "<" tag-name) (if (pair? (cdr node)) (for-each (lambda (pair) (display " ") (if (string? pair) (display pair) (begin (display (car pair)) (display "=") (write (cdr pair))))) (cadr node))) (display ">") (if (require-endtag? node) (begin(for-each sexpr->html2 (cddr node)) (display* "</" tag-name ">")))) (display node)))
(define (html->sexpr) (define (omit-tag? tag) (find (lambda (s) (eq? (car tag) s)) *omit-tag-symbol-list*)) (define (find-tag tag-string stack) (let ((tag (string->symbol (first-token tag-string 1)))) (find (lambda (s) (and (eq? tag (car s)) (car s))) stack))) (define (make-tag tag) (split-tag-attr tag)) (let loop ((c (read-char)) (stack '())) (cond ((eof-object? c) (if (pair? stack) (car stack) stack)) ((char=? c #\<) (let ((tag-string (read-token #\>))) (if (char=? #\/ (string-ref tag-string 0)) (let ((v (find-tag tag-string stack))) (if v (let loop1 ((stack stack) (r '())) (if (not (eq? v (caar stack))) (loop1 (cdr stack) (cons (car stack) r)) (begin (set-cdr! (car stack) (append (cdar stack) r)) (if (pair? (cdr stack)) (begin (set-cdr! (cadr stack) (append (cdadr stack) (list (car stack)))) (loop (read-char) (cdr stack))) (loop (read-char) stack))))) (begin (stdout-puts "警告:" tag "は対応関係が異常です。読み飛ばします。") (loop (read-char) stack)))) (let ((tag (make-tag tag-string))) (if (omit-tag? tag) (begin (set-cdr! (car stack) (append (cdar stack) (list tag))) (loop (read-char) stack)) (loop (read-char) (cons tag stack))))))) (else (let ((s (read-token #\< c))) (if (pair? stack) (set-cdr! (car stack) (append (cdar stack) (list s))) (stdout-puts "警告:" s "はどのタグにも所属してません")) (let ((xc (peek-char))) (loop (if (eof-object? xc) xc #\<) stack)))))))
807 :
デフォルトの名無しさん :02/05/16 21:26
Lisp板、今日はなんでこんなにレベル低いの...?
807=809
>>808 放置も出来ない厨房はすっこんでろと言われる罠
Lisp板? 確かにcar板やcdr板はあるけどさ
>>812 プログラム板をLisp板と勘違いしているだけ。
Lisp以外、眼中にないから。
>>814 lisperにとって括弧は空気みたいなものです。
Lisp・・・・初めて見たときはプログラムだと思わなかった・・・・
高級言語でプログラムを書くと、理由も無しに「んじゃこれを C で…」等と 言ってくる愚か者がいるんですが。みなさんはどう対処します? 高級言語の中でも、Lisp が最も顕著なもののひとつかなと思って。
818 :
デフォルトの名無しさん :02/05/16 22:22
>>814 括弧と括弧の谷間でムギュッ、が好きですが何か?
>>817 Cの括弧はふくらみがたりない
>>817 Cトランスレータ使うとか。
トランスレータが吐いたコードをメンテナンスする
気にはならんだろうけど。
820 :
デフォルトの名無しさん :02/05/16 22:51
処理系にあまり依存しない様なCトランスレータある?
(define Y (lambda (le) ((lambda (f) (f f)) (lambda (f) (le (lambda (x) ((f f) x)))))))
822 :
デフォルトの名無しさん :02/05/17 00:09
>>820 LISPからCへのトランスレータってlambdaとかあるから一筋縄じゃいかなそう。
一旦bytecode化してからやるのかな。
823 :
デフォルトの名無しさん :02/05/17 01:55
CLOSってどうよ?
824 :
デフォルトの名無しさん :02/05/17 02:54
>>823 ACL体験版使ってみれば?
普通のLISP関数と同様に扱えるのが強み。
ただしVariantが沢山ある。
実際、チープな処理系でもマクロの様なものがあればCLOSモドキは
いくらでも生産できる。これは凄いことなのかもしれないけど、
各々で独自のObjectSystem作れる事が逆に災いして、
そのシステム上でのプログラムを作っても他と交流できず
いつのまにか消滅して発展しないってパターンが多い気がする。
825 :
デフォルトの名無しさん :02/05/17 04:42
マルチメソッドディスパッチ
826 :
デフォルトの名無しさん :02/05/17 22:09
誰か list->csv csv->list 作ってください。宿題とかではないです。 インタフェースは、 (list->csv l)でリストlをcsvに直して標準出力に吐く、 (csv->list)で標準入力のcsvをlistにする。 入出力に使用するリストは ((r1c1 r1c2 r1c3 ...) (r2c1 r2c2 r2c3 ...) (r3c1 r3c2 r3c3 ...) ...) こんな感じで。 csvの引用符の処理は適当でいいです。
やだ
828 :
デフォルトの名無しさん :02/05/17 23:19
書けこのやろう
829 :
デフォルトの名無しさん :02/05/17 23:44
お前が、書け!
最近こんな応酬ばっか
831 :
デフォルトの名無しさん :02/05/18 05:05
>>826 Gaucheで
(use text.csv)
(define (csv->list) (port->list (make-csv-reader #\,) (current-input-port)))
(define list->csv (let ((w (make-csv-writer #\,))) (lambda (l) (for-each (lambda (r) (w (current-output-port) r)) l))))
832 :
デフォルトの名無しさん :02/05/18 11:13
read-char遅え。 やっぱバカ正直に1文字ずつ読みこんで懐石してくのは インタプリタでは荷が重いな。最低read-lineだな。
833 :
デフォルトの名無しさん :02/05/18 14:37
834 :
デフォルトの名無しさん :02/05/18 16:51
make-csv-reader make-csv-writer こんな関数あるの?
835 :
デフォルトの名無しさん :02/05/18 16:52
>>817 いるいる。しかも情報系の大学教授あたりでも。
卒論発表なんかで関数型言語の話をすると、
「CやJavaのような実在の言語には適用できないのでは?」とか発言するDQN教官。
お前らのせいでプログラミング言語の進歩が阻害されとるんじゃゴルァ
>>835 そりゃ教官の罠なんじゃないですか? 実は激しい Haskeller だったりして。
ま、違うだろうな。
837 :
デフォルトの名無しさん :02/05/18 17:13
>>822 lambdaそのものは、常にクロージャ(=「関数へのポインタ+自由変数の値」の構造体)
を作ることにすば、バイトコードにまでしなくても、わりと楽にできそう。性能はともかく。
それよりもガベコレが問題かも。
Boehm GCっていう、CやC++用のガベコレが使える環境ならいいんだけど。
838 :
デフォルトの名無しさん :02/05/18 17:34
839 :
デフォルトの名無しさん :02/05/18 17:35
named-letをlambdaに展開すると、こんな感じになりますが、 (let loop()(display 'hoge)(loop)) =>(((lambda(loop)(set! loop(lambda()(display "hoge")(loop)))) '())) これをCとかに変換しようと考えると、鬱になってきます。 tail_recursion_loop: display("hoge"); goto tail_recursion_loop; named-letのまま考えた方がいいんでしょうか。
自分はこんなの1)をこんな感じ2)に変換したいと思ってるんですが、 どれぐらいのコード書かないといけないんでしょうか。 if文や関数を(f)->f()に変換するぐらいはできますが、 末尾再帰の認識や変数のバインディングのところで躓いてます。 (gcなどの問題は棚上げして考えてます) 1) (define (list->csv l) (for-each1 (lambda (col) (let loop ((s col)) (if (pair? s) (begin (display (car s)) (if (pair? (cdr s)) (write-char #\,) (newline)) (loop (cdr s)))))) l)) 2) obj_t list2csv(obj_t l) { obj_t result = nil; obj_t args = l; for_each1: if (pairp(args)) { obj_t col = car(args); obj_t s = col; loop: if (pairp(s)) { display(car(s)); if (pairp(cdr(s))) { write_char(','); } else { newline(); } s = cdr(s); goto loop; } args = cdr(args); goto for_each1; } else { result = t; } return result; }
>>841 禿しく外出な話題だが、
なぜアリ物(Gambit-Cなど)ではだめなのか? 趣味?
まあ、あんまり凄い解析しないでちゃんと末尾再帰まで
実装するなら、Cのスタックは使わず、trampolineを使う
のが良いでしょう。
1. 元のSchemeプログラムは、関数呼び出しごとに別の
C関数に分けて変換する。
2. グローバルな変数fun, valと、引数を渡す仕組み
(グローバル変数や、配列で作ったスタック)を用意する。
3. トップレベルでは、
while (1) {
(*fun)();
}
みたいにする。
4. Scheme関数を呼び出すコードは、
(1)環境を閉じ込めた継続を作り、
(2)継続を配列で作ったスタックやヒープに退避し、
(3)引数をセットし、
(3)funに呼びたい関数を入れてreturnする。
5. Scheme関数からreturnするコードは、
(1)返す値をvalueに入れ、
(2)継続を取り出してfunにセットしreturnする。
頑張って解析すれば、継続や環境をなるべくヒープに
割り当てないようにできる。
(SICPが参考になる。)
>>842 ありがとうございました。
継続も考えるとさらに鬱になってきますね。
>なぜアリ物(Gambit-Cなど)ではだめなのか? 趣味?
趣味です。
アリ物でシンプルなやつがあればそれ参考にしたいんですけどね。
844 :
デフォルトの名無しさん :02/05/18 23:48
>>841 末尾再帰の判定は関数内を辿っていって、
例えば
(if test true false)ならば
test x
true false o
(begin seq1 ... seqn)ならば
seq1 ... x
seqn o
と末尾再帰可能か?を伝播していけばいけるんじゃないかと。
>>844 認識は簡単だけど、Scheme関数1つをC関数1つに変換するという
方針では、末尾再帰を実装できないよね。自分自身に再帰する
特殊な場合だけはgoto使えば良いけれども。
レスありがとうございます。
>>844 その様ですね。
条件式、関数の引数についてはx
とか。
>>845 named-letは多用するんで、
その辺をまず考えていきたいと思います。
ちょろっと書いてみましたが、
(sexpr->c
'(let loop ((s col))
(if (pair? s)
(begin
(display (car s))
(if (pair? (cdr s))
(write-char #\,)
(newline))
(loop (cdr s))))))
という入力に対し、
=>"{
obj_t s=col;
loop:
if (pair?(s)) {
display(car(s))
if (pair?(cdr(s))) {
write-char(,)} else {
newline()}
loop(cdr(s))
}
}
"
という文字列を返すところまでできました。
いまのところコード中には副作用無しです。
式文の終端のセミコロンや、letの右側のバインド式など、まだ課題は沢山ありますが。
「関数を関数に、ifをifに」 ってな具合いに変換するのは、すぐ壁に突き当たると思う。 SICPの5.5節を嫁。
848 :
デフォルトの名無しさん :02/05/19 06:47
関数を全部labelにしろ。
現在こんなかんじです。 いまのところソースは100行ぐらいです。 解析関数にローカル変数のリストを加えたので 末尾再帰loopシンボルの処理まではできました。 for-eachはlambda限定で1リストの決め打ちです。 (sexpr->c ' (for-each (lambda (col) (let loop ((s col)) (if (pair? s) (begin (display (car s)) (if (pair? (cdr s)) (write-char #\,) (newline)) (loop (cdr s)))))) l))) =>" { obj_t g162=l; for_each_g162: if (pairp(g162)) { obj_t col=car(g162); { obj_t s=col; loop: if (pair?(s)) { display(car(s)) if (pair?(cdr(s))) { write-char(,) } else { newline() } s = cdr(s); goto loop; } } g162 = cdr(g162); goto for_each_g162; } else { result = t } } " ※実際はこんな綺麗にインデントはされません
850 :
デフォルトの名無しさん :02/05/19 15:07
末尾再帰じゃないnamed-letはどんなコードになるの?
>>850 末尾再帰判定で弾かれるので最初の出力の様な、ただの関数呼び出しになります。
今のところloop関数は別途出力される予定はないので、おかしな事になります。
手動でコピペして修正する必要があります。
852 :
デフォルトの名無しさん :02/05/19 21:32
>>852 小さい整数と大きい整数の演算では速度が違うからね。
そのくらいのずれはしょうがない。ぴったり2倍になるわけはない。
854 :
デフォルトの名無しさん :02/05/19 22:16
計測には誤差はつきものだね。
855 :
デフォルトの名無しさん :02/05/19 22:28
問題:データはその予想を支持するか。違いがあれば説明できるか。 解答:誤差だと思われ。 でいいんですね。ありがとうございますた。
GC時間は差し引いた?
857 :
デフォルトの名無しさん :02/05/20 18:15
>>847 横着なソースだと関数引数やifの条件式の中にletとかあったりするよね。
(func (let ...))だったら
(let ((tmp (let ...))) (func tmp))
みたいにすればいいかな。
858 :
デフォルトの名無しさん :02/05/20 19:58
Cに変換すると速度はどれぐらい違うんでしょうか?
859 :
デフォルトの名無しさん :02/05/20 21:45
CをLispに変換すると、どれくらい速いんでしょうか!
>>858 S式をインタプリトするのと比較して?
元のインタプリタにもよるけど、
単純な変換だと、実はそれほど速くならない。
高速なインタプリタと比較すると、
普通のリスト処理だと3倍くらいじゃないか。
整数演算とかだと、うまく型宣言すると
30倍くらいになる。
まず、「S式をたどって式の種類を判別する」
オーバーへッドを省くだけで、やることが変わ
らないような変換だとせいぜい3倍。関数をイ
ンライン展開しないとそれ以上の速度向上は
望めない。
次に、GCが遅いようなインタプリタだとどう
やってもだめ。例えば処理時間の40%がGC時間
のインタプリタは、どんな凄い最適化をしても
(メモリ割り付け量が減らない限り)2.5倍に
しか速くならない(アムダールの法則だね)。
>>859 開発速度は桁違いに早くなるでしょう。実行速度はわからん。
全体として見れば、下手な奴が書く C プログラムよりずっと良いと思う。
ようやくある程度使えそうなものができました。(インデント処理も含め) schemeコード副作用なしで、500行ぐらいです。 まだ普通の再帰、継続、クロージャその他もろもろに未対応ですが。 ここまで思ったより短い期間で作れたんで満足してます。以上。 変換結果 obj_t list_to_csv(obj_t l) { obj_t result = nil; { obj_t g2 = l; for_each_g2: if (pairp(g2)) { obj_t col = car(g2); { obj_t s = col; loop: if (pairp(s)) { display(car(s)); if (pairp(cdr(s))) { write_char(','); } else { newline(); } s = cdr(s); goto loop; } } g2 = cdr(g2); goto for_each_g2; } else { result = t; } } return result; }
なんか、むちゃくちゃレベル高くなったな。 いっときはクソスレに片足突っ込んでたのに(w
864 :
デフォルトの名無しさん :02/05/21 11:04
865 :
デフォルトの名無しさん :02/05/21 11:14
実際に走らせてみたら? (cdr alist) => ((b (2))) (car ((b (2)))) => (b (2)) (cdr (b (2))) => ((2))
866 :
デフォルトの名無しさん :02/05/21 14:05
(cadr alist) => (b (2)) (cdr '(b (2))) => ((2)) じゃねーの? 慣れると cadr→2番目 cdr→残り と脳内変換されるよ。
867 :
デフォルトの名無しさん :02/05/22 00:32
WindowsでLISPやる場合はどんな処理系がありますか?
868 :
デフォルトの名無しさん :02/05/22 00:36
xyzzy
869 :
デフォルトの名無しさん :02/05/22 00:38
emacs-lisp
870 :
デフォルトの名無しさん :02/05/22 00:42
871 :
デフォルトの名無しさん :02/05/22 00:47
LISPからVBにトランスレートするコード誰か書いて!
872 :
デフォルトの名無しさん :02/05/22 00:53
>>871 リストってVBで表現できたっけ?
Variant型の配列使うしかないのかな。
874 :
デフォルトの名無しさん :02/05/22 01:54
875 :
デフォルトの名無しさん :02/05/22 02:42
Gaucheってcygwinで動くんだね。
>871 VBに変換してどうするんだろう
877 :
デフォルトの名無しさん :02/05/22 02:55
LISPからトンパ語にトランスレートするコード誰か書いて!
ネイティブコードやJavaVMとかに変換した方がいいとおもう。 変換後、すぐ実行できるし。 メンテは大変かもしれないけど。
879 :
デフォルトの名無しさん :02/05/22 03:59
>>878 実際オープンソースでネイティブ変換してるやつ、
ググって探してみたけど無いもんだね。製品ばっかり。
JavaVMはKawaってのがあるみたいだけど。
880 :
デフォルトの名無しさん :02/05/24 16:37
(method object ...) を (object.method ...) ってやってる処理系ってありませんか? '.'をフックすればできるのかな。 見た目的にマルチメソッドではなくなってしまうだろうけど。
881 :
デフォルトの名無しさん :02/05/24 18:48
Arcが x.y を (x y) と読む、とかいう略記法を採用していたような。 CommonLispで '.' のリーダーマクロを書いて、x.y を (slot-ref x 'y) と読ませるようにしたことはあります。
違った。CommonLispはslot-valueだ。
883 :
デフォルトの名無しさん :02/05/24 21:47
>>881 ありがとう。
x.y.zの場合は(slot-ref (slot-ref x 'y) 'z)か。
>Arcが x.y を (x y) と読む、とかいう略記法を採用していたような。
Arcって実装は存在するのかな。
884 :
デフォルトの名無しさん :02/05/24 22:44
>>883 全部とは言わないけど、ほとんどマクロでなんとかなると思う。
既存のsyntaxに対しての上書きもあるのが問題だけど。
Arcのラッパーマクロ集みたいなの公開してくれないかなあ。
(object message args ...) 組み込み apply を再定義できないものでしょうか。 オブジェクトを表現するのにクロージャとタグを使って、 (define apply (let ((orig-apply apply)) (lambda (proc args) (cond ((object? proc) (dispatch proc args)) (else (orig-apply proc args)))))) みたいな感じで出来ればいいなぁ、と。
886 :
デフォルトの名無しさん :02/05/24 22:56
>>885 SLIBが動く様な処理系ならapplyの再定義なんかは普通にできると思うよ。
あれのtranscriptの実装は入出力全部再定義してるし。
887 :
デフォルトの名無しさん :02/05/24 23:03
>>885 あ、良く見たら組み込みapplyの方ですか。
CommonLispみたいにフックを登録できる様な処理系じゃないと。
現状のschemeの規格範囲内では無理です。
888 :
デフォルトの名無しさん :02/05/24 23:12
内部に手を加えない手段としては、objectをclosureにして、 もう一段上でdispatchする方法があります。(過去スレにありますけど。) これだとscheme規格範囲内での実装ができます。
>>888 ありがとう。SICP を読んでいるので、一段上で dispatch するやりかたは
愛用させてもらってます。
((obj 'msg) args ...) の形に書き換えるマクロを作ったりしたのですが、
なんだかなーと思っていた所なんですよ。
890 :
デフォルトの名無しさん :02/05/26 00:29
Float-Point Number Lispって論文読んだことある人いる?
検索しても密館内。 もう少し正確な論文名きぼん。
892 :
デフォルトの名無しさん :02/05/26 01:00
>>889 procedure?とobject?のきリ分けができなくても困らない?
>>892 ん? 質問の意図するところが分からないんですけど。
894 :
デフォルトの名無しさん :02/05/26 16:15
sicpの図形言語を実際にやってみたいんですけど、 なにとなにをインストロールすればよいのでしょうか? OSはWindowsです。
895 :
デフォルトの名無しさん :02/05/26 16:44
>>893 例えば
(define object1 (make-object <a-class>))
として<a-class>に属するobject1を作ったとして、
そのobject1が<a-class>なのかプリミティブなのかを判定したくても、
中身はclosureそのものだから、(class? object1)
とかが作れない。
(define (class? object) (procedure? object))
でもいいの?ってこと。
クラスメソッドとして(object 'typeof)というのを作っても解決しないし。
>>895 その場合はタグを付ければ良いんじゃないでしょうか。
演繹的に実装する場合、いずれにせよ何らかのプリミティブに
置き換えられるわけで。
897 :
デフォルトの名無しさん :02/05/26 23:35
>>896 いや、タグを付けるのはいいんだよ。
けどそうなると特別扱いしなくてなならんので、その辺どうなのかということ。
どのみち処理系に手を加えるなりしないとこの問題は解決しそうにない。
(method object)形式なら話は簡単なんだけど。
898 :
デフォルトの名無しさん :02/05/26 23:51
名前に連結されてるdot(.)にフックを持てる様な処理系なら (object.method-a.method-b) に対して (method-b(method-a object)) や ((object 'method-a) 'method-b) に変換するのは可能でしょう。 あたかも事前に (define (object.method-a.method-b) ...) としていたかの様に使える。 既存のdot表記とは、シンボルとくっついてる限り区別できるから 互換性が保てるはず。
シンボル以外の任意の式だと…? ((if (foo) object1 object2).method1 ...) これは無理だよね。
>>897 その前に、僕のどの発言に対しての意見なのでしょうか?
議論がすれ違っているように思えるんですけど。
901 :
デフォルトの名無しさん :02/05/27 00:33
>>898 こういうのできたら面白いよね
>(define a (list 'b 'c 'd))
>(a.car)
=>b
>(a.cadr)
=>c
>(a.cdr)
=>(c d)
>>900 (object method)に対してapplyしたい
>>885 ↓
objectをclosureにすればいい
>>888 ↓
そうなるとprocedureとの区別がつかない
>>892 ↓
意味がわからない
>>893 に対してのレスのつもりなんだけど。
特別扱いはapplyの時ね。
903 :
デフォルトの名無しさん :02/05/27 01:02
(object method-selector arg1 arg2 ...)っていうのをばんばん使うなら、
>>897 の言うように実装を隠す機構が必要だと思うな。
それにarg1でdouble dispatchingするくらいなら、
CLOS風のgeneric functionがelegantだと思うし。
904 :
デフォルトの名無しさん :02/05/27 01:08
>>901 あくまでもシンボル(読みこみ時に解決)に対してだから、
lambdaやletかますしかないかと。
((lambda(a)(a.method1 ...)) (if (foo) object1 object2))
(let ((a (if (foo) object1 object2)))(a.method1 ...))
あと、右辺に適用できるのが1引数を取る関数になってしまう様な。
(a.method1 b)みたいなことはできないと思う。
(a.method1 b)を
((lambda args (apply method1 (cons a args)) b)
に変換するならできるかもしれないけど。
905 :
デフォルトの名無しさん :02/05/27 15:30
質問です。 smob (smobsか?) ってなんですか? データ構造みたいなんだけど、googleとかで探しても 使ってる場面しか見つからなくて、意味が わかりません。
906 :
デフォルトの名無しさん :02/05/27 16:41
907 :
デフォルトの名無しさん :02/05/27 16:47
The term "smob" was coined by Aubrey Jaffer, who says it comes from "small object", referring to the fact that only the CDR and part of the CAR of a smob's cell are available for use.
908 :
デフォルトの名無しさん :02/05/27 16:54
かぶった
910 :
デフォルトの名無しさん :02/05/27 17:20
>>904 *dot-hook*というドット連結シンボルを読みこみ時に呼び出される
フック関数があるとしたら、こんな感じになる。
;argsはドットから切り離されたシンボルのリスト
(define (*dot-hook* args)
(let loop ((x (cdr args))(expand (car args)))
(if (pair? x)
(loop (cdr x)
(if (pair? (cdr x))
;ドット連結が続くなら1引数を取る関数しか使えない
(list (car x) expand)
;最後のシンボルに対しては外部から引数を取ることができる様にする
`(lambda args (apply ,(car x) (cons ,expand args)))))
expand)))
>(define a 'string)
>(a.symbol->string.string-append "-append")
=>"string-append"
(a.symbol->string.string-append "-append")
は
((lambda args (apply string-append (cons (symbol->string a) args))) "-append")
と変換される。
名前でアクセスする必要がある&途中の関数に対しては1引数しか取れない、
という限定的なものだけど。
なるほど、Guileの用語でしたか。 どうもありがとうございます。
912 :
デフォルトの名無しさん :02/05/27 20:09
>>910 いっそのこと、
a.method<c,d>
=>(method a c d)
に変換するってのはどお?
a.methodとした場合はclosureを返す。
a.method<c,d>.method<e,f>
(a.method<c,d>.method e f)
こういう風に両方で書けるし。
でも結局<>内はシンボルなんだなあ。
913 :
デフォルトの名無しさん :02/05/28 03:11
>>912 いいね。
ただしカンマの間に間違えて空白とか入れちゃうと意味変わるのが怖いけど。
ただのa.method<c,d>.methodというシンボルに対してのリーダー展開
マクロってだけだからねえ。
これ以上はname<〜>を別の意味に解釈する(内部)readを作る必要があるね。
914 :
デフォルトの名無しさん :02/05/28 07:11
>>910 1つのS式の読みこみ毎に呼ばれる*READ-HOOK*関数を定義できるとすれば、
もうなんでもありだと思う。
1つのS式つーのは、読みこむS式が
(e (a b c) (d))
だとすると
(a b c) ... x
(d) ... y
(e x y)
のパターンそれぞれで呼び出されるってこと。
xとyはそれぞれの*READ-HOOK*の結果が入る。
S式の一番根っこの時点でexpandかければ、macroの展開も同時に
作用させられる。
CommonLispにも同様の機能があるけど、S式の読みこみ段階で
1度処理が走るだけだから、後のeval実行プロセスには影響ない
ってのがかなり使えると思う。
処理系を自作で持ってたるする人は試してみよう。
せっかくLispなのに中置記法やカンマなんて出てくるのは欝。
916 :
デフォルトの名無しさん :02/05/28 17:42
>>914 >のパターンそれぞれで呼び出されるってこと。
evalの評価順序と逆になる?
eがマクロだとしたら、(a b c) (d)を先に変更するのはまずい気が。
eがcaseみたいな特殊なカッコの使い方をする時とか。
>>902 最近忙しくて、返信が遅くなってしまいました。
ずーっとこの問題について考えていたんですが、やっぱり
(method object args ...) が一番な気がしてきました。
918 :
デフォルトの名無しさん :02/05/28 23:54
ソウダロソウダロ
>>915 カンマ→ピリオドじゃねーの?
,はbackquoteで使うよん。
920 :
デフォルトの名無しさん :02/05/29 07:56
質問です。 Case sencitiveなSchemeの string->symbol と string->symbolは、 1-to-1 だと仮定して大丈夫なんでしょうか? また、 その二つの合成関数は常にidentityと仮定してよいんでしょうか?
921 :
デフォルトの名無しさん :02/05/29 19:24
>>920 >string->symbol と string->symbolは、1-to-1 だと仮定して大丈夫なんでしょうか? また、
symbol->stringとstring->symbol
の間違いじゃない?
この辺は規格書とr4rstest.scm見ればわかると思う。
>その二つの合成関数は常にidentityと仮定してよいんでしょうか?
identityってなに?
922 :
デフォルトの名無しさん :02/05/29 19:34
>>916 >evalの評価順序と逆になる?
逆になります。
S式の根っこで呼び出した方がいいかも。
923 :
デフォルトの名無しさん :02/05/29 22:34
substringはあるのにsublistやsubvectorが無いのは何ででしょうか。
>>921 「...の間違い」
そうです。
R5RSをちらっとみてみた範囲では、例はあげられていたものの、
単射でなければならないとは書いてないような気がして。
ところで、RnRS以外の規格書ってあるんですか?
identity 云々は、
∀x (xはSchemeのオブジェクト)
{(string->symbol (symbol->string x))
≡ (symbol->string (string->symbol x))
≡ x}
(あるいは、
{(lambda (x) (string->symbol (symbol->string x)))
≡ (lambda (x) (symbol->string (string->symbol (x))
≡ (lambda (x) x))}
は仮定して大丈夫なんでしょうか?という意味です。
あ、いけね。前半は ∀x (xはSchemeのシンボル) {(string->symbol (symbol->string x)) ≡ x} ∧ ∀x (xはSchemeの文字列) {(symbol->string (string->symbol x)) ≡ x} なのかどうか、です。 (後半の式もかっこの対応が変だけど。)
926 :
KOKUYO :02/05/30 14:06
質問!!member関数を、第2引数のリストの深いレベルまで 第1引数を探索して取り除くように拡張した関数はどうやって 作ればいいんですか?
>>926 なんだマルチか。
関数型言語スレにヒント書いておいたよ。
>>926 memberを自作してcarがconspな時に再帰する様にしてけばつくれるよ。
取り除くって事は破壊/非破壊の2パターン作れるかと。
この場合非破壊バージョンはちょっと難易度高いかも。
929 :
デフォルトの名無しさん :02/05/30 17:17
>>924 >(lambda (x) (string->symbol (symbol->string x)))
>(lambda (x) (symbol->string (string->symbol x)))
>(lambda (x) x)
これ、それぞれの意味全く違うと思うけど。
何がしたいの?
あ、質問の意味がわかった(きがする) >(lambda (x) (string->symbol (symbol->string x))) 引数と戻値はeqv?で一致すると保証されてる。 >(lambda (x) (symbol->string (string->symbol x))) 引数と戻値はeq?で一致すると保証されてる。 >(lambda (x) x) 引数と戻値はeq?で一致すると保証されてる。 これでいいかな? symbolはuniqueなので比較は同一だけど、 一旦stringになった場合、それが同値(コピー)なのか同一なのか は保証されていないって事で。
>>930 逆だった
>(lambda (x) (string->symbol (symbol->string x)))
引数と戻値はeq?で一致すると保証されてる。
>(lambda (x) (symbol->string (string->symbol x)))
引数と戻値はeqv?で一致すると保証されてる。
>>929 これ、それぞれの意味全く違う[...]
どうもありがとうございます。
よく考えたみたら、そりゃそうですよね。疑問点を
頭の中で明確にする前に質問書込んでしまいました。
すみません。
933 :
デフォルトの名無しさん :02/05/30 19:54
誰かguile-gtkのwindowsバイナリ作ってください。 おねがいします。
934 :
デフォルトの名無しさん :02/05/30 20:06
935 :
デフォルトの名無しさん :02/05/30 20:31
>>923 なんでだろね。対称性悪いよね。
Gaucheにはsubseqがあるな。
(use gauche.sequence)
(subseq '(a b c d e) 1 4) => (b c d)
(subseq '#(a b c d e) 1 4) => #(b c d)
(subseq "abcde" 1 4) => "bcd"
936 :
デフォルトの名無しさん :02/05/30 21:10
>>920 ちょっと(or たくさん)外してるかも知れませんが、
common lisp の
Read-read consistency
Print-read consistency
Print-print consistency
を調べてみると、考えをまとめる手がかりになるかも知れません。
この辺を突っ込んで行くと、2-lisp、3-lisp とどんどん腐海世界に
(scheme からは離れて行っちゃうけど)入り込んで行けます。
Gauche には debugger はないのか?
938 :
デフォルトの名無しさん :02/05/31 00:39
>>937 debuggerとはソースの修正も入るやつ?
インテリジェントなやつは多分ないと思う。
エラー個所の特定ならtraceするって手段があると思うけど。
たぶんそれぐらい入ってると思う。(この手はLISP系だと作るのが簡単)
ステップ実行もできるといいとは思うけどね。
evalされる毎に式を表示してリターン押すと実行とか。
>>923 > substringはあるのにsublistやsubvectorが無いのは何ででしょうか。
そう言う意味での「完全さ」を求めるとCommon Lispみたいに肥大しちゃう
から。(stringとlistはそもそもn番目の要素のアクセス法が全く異なるし。)
940 :
デフォルトの名無しさん :02/05/31 07:08
>>939 CommonLispみたいに汎用的なのはマクロで作って、
:stringみたいに型を明示的に指定するってのはどうですか。
実行時判定を行わずに展開時で切り分けできるし。
>>936 こういう誘導はとても助かります。どうもありがとうございます。
>>936 申し訳ありませんが 2-lisp,3-lispについて解説しているページを教えて戴けませんか?
ぐぐっても、まともにヒットしてくれません。
>>942 http://www2.parc.com/publications/pubs-hst.html の
Interim 3-LISP Reference Manual
Brian C. Smith, Jim des Rivieres, July 1984
The Implementation of Procedurally Reflective Languages
Jim des Rivieres and Brian C. Smith, July 1984
Reflection and Semantics in LISP
Brian C. Smith, June 1984
;; "3-Lisp"と引用符付けてる?
944 :
デフォルトの名無しさん :02/06/01 16:18
945 :
デフォルトの名無しさん :02/06/01 19:54
みなさん、Linux上でおすすめのCommon Lisp処理系は何ですか? Allegroって凄く高いですよね?
946 :
デフォルトの名無しさん :02/06/01 19:57
947 :
デフォルトの名無しさん :02/06/01 22:29
>>945 それ知りたい。今使ってるのはGCLだけど、他にあれば教えてください。
>>945 確かに高いが、すごくってほどでもない。
個人じゃ手が出ないが
949 :
デフォルトの名無しさん :02/06/01 22:55
ACLなん万だっけ?20万ぐらいで買えた?
じゃ2年ローンで・・
>>945 LinuxだったらGNUの洗礼を受けたgclかな。
メンテナンスされてるのか知らないけど。
951 :
デフォルトの名無しさん :02/06/01 23:39
952 :
デフォルトの名無しさん :02/06/01 23:49
953 :
デフォルトの名無しさん :02/06/02 00:28
954 :
デフォルトの名無しさん :02/06/02 00:36
>>953 Windowsバイナリがみあたらないんですが、
無いんでしょうか。
955 :
デフォルトの名無しさん :02/06/02 00:41
956 :
デフォルトの名無しさん :02/06/02 00:41
そろそろ次スレかなあ。
959 :
デフォルトの名無しさん :02/06/02 01:45
>>958 >価格
>・デスクトップタイプ プロフェッショナル版 130万円〜
>_ エンタープライズ版 200万円〜
>・サーバータイプ プロフェッショナル版 260万円〜
>_エンタープライズ版 400万円〜 アカデミックプライスもあります。
ACL5だから情報がちょっと古いとはいえ、
こりゃ個人では手がでませんな。
関係ないけど
>MOEBIUS (メビウス)
>Common Lisp to C translator 理想の言語変換ツール
>価格
>1,000,000円より
ってどんなだろ。
lispをcに変換するのは、schemeをcにするよりは継続とかがない分
簡単かも。
CommonLispを完全に変換するのは量的に苦労しそうだけど。
>>959 ライブラリとしてインタプリタを持っていて、変換しきれない分はインタプリタで実行。
perlccと同じ
961 :
名無しさん@Emacs :02/06/02 11:22
それって、えーとR田中二郎???
どなたか そろそろ次スレ立ててください。 自分は「スレッド立てすぎです・・」が出てしばらく立てられそうにないです。
Common Lisp の本は出ましたか?
さあ歌え。
969 :
デフォルトの名無しさん :02/06/10 17:38
970 :
デフォルトの名無しさん :02/06/14 23:20
すいません、 だれかスタンダードなLISPてどれか教えていただけませんか 処理系がおおくて。
>>970 commonという名を持つLISPがいますがね。
>>970 Common Lispなら、
GCL, CLISP, LispWorks(パーソナルはフリー)などなど。
探せばいくらでもあると思うんだけど。
O)-< O\-< O|-= O|-= O(-<
974 :
デフォルトの名無しさん :02/07/14 00:04
SICP に出てくる cons-stream ってどう書いたらいいんですか? 定義が載ってないので stream 系の例題が全部試せないし、自分で書こうにも stream も macro もわかってないのでお手上げです。(多分 macro で書けるん だろうと思っているのですが) ;; stream 系の手続き実装してる処理系使うのが一番早いんでしょうけど。
旧スレageられてもねぇ…
ごめんなさい。旧スレ眺めてたら誤爆してしまいました。
>>974 素直に delay 使えば出来ません?
978 :
デフォルトの名無しさん :02/07/16 06:16
もうちょっとヒネレよ このドアホ
こっちはもうsageてくれ
981 :
デフォルトの名無しさん :02/07/16 16:07
age