1 :
デフォルトの名無しさん :
02/09/09 17:38
2 :
デフォルトの名無しさん :02/09/09 17:39
3 :
デフォルトの名無しさん :02/09/09 17:39
4 :
デフォルトの名無しさん :02/09/09 17:40
5 :
デフォルトの名無しさん :02/09/09 17:40
6 :
デフォルトの名無しさん :02/09/09 17:40
7 :
デフォルトの名無しさん :02/09/09 17:41
10 :
デフォルトの名無しさん :02/09/09 19:13
スレ立てお疲れ。 こっちはもう6か。 ところでマ板のlispスレどこいった?
11 :
デフォルトの名無しさん :02/09/09 20:05
12 :
デフォルトの名無しさん :02/09/09 20:16
13 :
デフォルトの名無しさん :02/09/09 20:37
16 :
デフォルトの名無しさん :02/09/09 21:17
18 :
デフォルトの名無しさん :02/09/09 21:41
19 :
デフォルトの名無しさん :02/09/09 21:46
21 :
デフォルトの名無しさん :02/09/09 21:59
22 :
デフォルトの名無しさん :02/09/09 22:07
23 :
デフォルトの名無しさん :02/09/09 22:11
25 :
デフォルトの名無しさん :02/09/11 13:59
やっとでたか…つーか3ヶ月ぐらいまってたな…
とりあえずlisperなら全員買え!って感じの内容
ぽーる・ぐらはむ だと思ってた… On Lisp も買いたい…どうしよ(´Д`)
原書は何であんなに高いんだろ。 翻訳はあんまり読みたくないんだけど。でも安いから迷う。
31 :
デフォルトの名無しさん :02/09/11 18:52
>>19 のvarかなり使いやすいんで、後始末してくれるやつ作りました。
(var/finally <変数名> <初期化式> <後始末(変数名使用可)> ...)
使い方はこんな感じで。
(var/finally ptr (malloc 100)(free ptr) ...)
見ての通りunwind-protect使える処理系で動作します。
(define (var/finally-expand l)
(if (and (pair? (cdr l)) (symbol? (cadr l)) (pair? (cddr l)))
`(let ((,(cadr l) ,(caddr l)))
(unwind-protect
(lambda() ,@(var-sequence-expand (cddddr l)))
(lambda() ,(cadddr l))))
(error "syntax : var/finally <name> <value> <finally>" l)))
(define-macro (var/finally . body) (var/finally-expand (cons 'var/finally body)))
(var size 10 var/finally ptr(malloc size)(free ptr) ...)
みたいなことしたい場合は、var-sequence-expandにvar/finallyを
追加する事。
ほとんどプログラミングしたことの無い、大学にも逝ってない、仕事はLISPと無関係な厨房に おすすめの書籍を教えてくだちい。
>>32 あのスレの8で、自分でカキコしてたANSI Common Lisp の本でいいんじゃない?
一応入門書みたいだし。
LISPの本は地雷みたいな変なの無いから、どれ読んでもそれなりに覚えられると思うよ。
買う前にまず図書館行くのを薦めるけどね。
>>32 書籍っていうか、適当に検索すればいいとこ見つかるよ、
gauche-gtk (・∀・)イイ!!
>>35 凄いよね。Gauche のおかげで scheme 勉強できた。
まだ scheme のオブジェクト指向拡張に慣れる事が出来ないけど。
>>29 タイポは多いけど、素直な訳だとおもいますよ。
僕も訳書って嫌いだけど、これなら大丈夫かな。
好き好きだけど。
38 :
デフォルトの名無しさん :02/09/12 09:23
みなさん、Scheme学んだあとそれをどう使われてますか? 自分はまだSICPの2章までを学び終えたばかりなのですが、 どうも作りたいものが浮かんで来ません。 入出力中心のプログラムならC++や他の言語の方が 適してると思うし。。。 何か高尚なプログラミングの課題を持っていて 必要にせまられていないとだめなのかなあ。。。 それともセンスがないだけなのか、、、 とりあえず最後まで読んでから考えろってことですね。 失礼しました。
>>38 結構学んだあと何を作ろうか思い浮かばないのがLisp、Schemeのいいところです、
やっぱり最後まで読んで、悟りを開いてから考えましょう。
というけど、自分も何を作ったらいいか分からない罠。
>>38 最後まで読むのは良いこと。
でも、最後まで読んだってなにか思い浮かぶとは限りません。
ある日突然、プログラム書こうと思う日が来る人もあれば、
どんなに高尚な理論を消化していてもいなくても、プログラムを書く動機を
得ない人は沢山いると思います。
でも、ある日、そうだプログラム書こう、と思うときがやってきた場合には、
SICP読んでてSchemeを知ってるってのは、確実にとんでもないadvantageだと思いますよ。
もし、そういうときが来なかったとしても、何かをきちんと理解しているってのは
それだけでそれなりに良いことだと思う。(それなりにね。)
アレグロの体験版使った人いる?、正直どうだった?
44 :
デフォルトの名無しさん :02/09/12 22:58
俺も暇さえあればなー
暇さえあれば何よ?
46 :
デフォルトの名無しさん :02/09/12 23:15
( ´_ゝ`) 暇さえあればなー
みんなはLispのコード書くときにどのエディタ使ってる? やっぱりEmacs?それともxyzzy?
メモ帳
cat > nyaa.scm
53 :
デフォルトの名無しさん :02/09/13 00:42
Excelで書いてる人いる?
>>53 おお、いいねぇ。Excel-Lisp か。誰か作ってよ。
vi 系って indent してくれるんだろうか… vim ならできそう。
>>54 VBAってリスト扱えたっけ
でも、セルをevalするってのは楽しそうだなー
>>55 vimはインデントしてくれるけれど、ちょっと重いのが難点。
でも結構いいよ。
viなんてサーバのメンテ以外で使いたくない
それでも俺はvi(vim)を使いつづける。
>>38 AlexandrescuのTypelistを使うときに役に立つ(かな)
61 :
デフォルトの名無しさん :02/09/13 14:23
32bit環境だとconsは8バイトですか? Gaucheも8バイトかな。
62 :
デフォルトの名無しさん :02/09/13 21:17
ANSI Common Lisp本買ってきた。 なかなか深い所まで掘り下げて書いてある感じ。 これで3400円は安いかも。
>62 そう?あんまりたいしたこと書いてなさそうだったけど。 なんか薄かったし。
64 :
デフォルトの名無しさん :02/09/13 21:48
少なくともケントディヴィグのscheme本よりまし。 (あっちの方が400円安いけど)
65 :
デフォルトの名無しさん :02/09/13 22:40
>>61 Gaucheは8バイトだった気がする。
アラインメントの関係で下位bitが空いてるんだよね。
CやASMベースのLISP処理系はほとんど8バイトなんじゃない?
66 :
デフォルトの名無しさん :02/09/14 07:23
mini-scheme(tiny-scheme)は10バイトですが何か? パディングの関係で12バイトかもしれん。
SICPを初めて読みましたが章の頭にある引用はとても面白いですね。 3章の状態を扱った章で、ヘラクレイトスを持ち出すあたりは カッコいいなあと思いマスタ。
68 :
デフォルトの名無しさん :02/09/15 02:13
結局こういうことしてしまうよ。おいらは。 (de n2s number->string) (de s2n string->number) (de i2c integer->char) (de c2i char->integer) (de l2s list->string) (de s2l string->list) (de c= char=?) (de c!= (la(c)(not(c= c)))) (de c< char<?) (de c> char>?) (de c<= char<=?) (de c>= char>=?) (de ci= char-ci=?) (de ci!= (la(c)(not(ci= c)))) (de ci< char-ci<?) (de ci> char-ci>?) (de ci<= char-ci<=?) (de ci>= char-ci>=?) (de s= string=?) (de s!= (la(c)(not(s= c)))) (de s< string<?) (de s> string>?) (de s<= string<=?) (de s>= string>=?) (de si= string-ci=?) (de si!= (la(c)(not(si= c)))) (de si< string-ci<?) (de si> string-ci>?) (de si<= string-ci<=?) (de si>= string-ci>=?)
>>67 そういう一般教養って、ボディーブローみたいに後々効いてくるもんなんだけど、
あんまり大事にはされてないよね。
71 :
デフォルトの名無しさん :02/09/15 20:12
htmlの変換のやつ使ってみたけど、やっぱ完全に変換するには それなりに解析しなきゃだめだね。 HTMLの場合、終端タグがあっても入れ替えの問題がある。 <TABLE><TR><FORM METHOD=POST ACTION="./hoge"> <TD NOWRAP WIDTH="" BGCOLOR="#5F9EA0"> <INPUT TYPE="submit" VALUE="更新"> </TD></TR></form> </table> こいうの結構あった。(TRとFORMの終端タグが入れ替わってる) </TR>を読んだ時、<FROM>が省略されたとみなして処理されるから、 対応してない</form>で警告が出た。 XMLやXHTMLならこんなことは起きないけど。
>>71 それをまた逆変換すると、<TR><FORM>....</FORM></TR>
になるだろうから、パーサ側には優しい出力になるんじゃない?
意味的に変化しないのはたまたまかもしんないけど。
73 :
デフォルトの名無しさん :02/09/15 21:29
Gaucheでslibのデータベース使った。 (use slib) (require 'database-browse) (define zrdb (create-database "zosho.db" 'alist-table)) (define nengo-desc-creator ((zrdb 'create-table) '年号デスク '*columns*)) ここまではOKだけど、下が駄目です。なぜなんでしょう? ((((zrdb 'open-table) '年号デスク #t) 'row:insert*) '((1 #t 年号 symbol? symbol) (2 #f 始め #f integer) (3 #f 終り #f integer)) ) *** Error: string required, but got row:insert Stack Trace: _______________________________________ 0 (rdms:error 'row:insert "row present:" row) At line 435 of "/usr/share/slib/rdms.scm"
トレースでわかんない?
75 :
デフォルトの名無しさん :02/09/15 21:57
>>74 トレースから下に変更はしてみました。でも、私には
理解不能でした。
((((zrdb 'open-table) '年号デスク #t) "row:insert*")
(略)*** ERROR: bad procedure: #f
Stack Trace:
>>75 いや、スタックトレスの方じゃなくて、
関連する関数をtraceに関連付けて呼び出すって方法。
(trace func1 func2 func3)
(func1 args) ;実行
↓
(func1 args) call
(func2 args) call
(func3 args) => result1
(func2 args) => result2
(func1 args) => result3
こんな出力が得られるはずだけど・・
Gaucheは知らないけど、trace(またはその代わり)ぐらい入ってると思うよ。
SLIB使ってるみたいだから、作者の知らない不具合なのかもしれないけどね。
あ、なんでtraceを薦めるのかは、 何を引数にして、何を返したかが直ぐわかるって理由ね。 動的closureに対しては適用できないけど。 (処理系によっては内部で持ってる事がある)
なんで英語なんだよー
>>79 投稿は日本語可なようだ。
sf.netだから仕方ない。
81 :
デフォルトの名無しさん :02/09/16 00:43
ポインタが無いと、↓の様なテーブルをalistに変換するやつとか一苦労しない? substringでやったけどインデックス操作がかなり大変だった。 (テーブル仕様:各カラムの区切り位置は先頭行ヘッダの各トークンの開始位置から抽出する。) >cat test.tbl destination gateway flags use hopcnt expire pksent default 192.168.0.3 BU 51551 0 0 51551 192.168.0.0/24 link#1 U 0 0 0 0 192.168.0.1 192.168.0.2 BA 0 0 0 0 (with-input-from-file "test.tbl" (read-text-table)) =>(("destination" "gateway" "flags" "use" "hopcnt" "expire" "pksent") ("default" "192.168.0.3" "BU" "51551" "0" "0" "51551") ("192.168.0.0/24" "link#1" "U" "0" "0" "0" "0") ("192.168.0.1" "192.168.0.2" "BA" "0" "0" "0" "0"))
82 :
デフォルトの名無しさん :02/09/16 01:06
苦労の跡。(varマクロ使用。shared-substringが無い処理系だと効率悪い。) (define (read-text-table) (var head (gets-skip-null-line) var headlen (string-length head) var delim " \t" var delim-list (let loop ((r '()) (spos (skiptoken head " \t"))) (if (< spos headlen) (var epos (+ spos (skipdelimiter (shared-substring head spos) delim)) (loop (cons epos r) (+ epos (skiptoken (shared-substring head epos) delim)))) (reverse r))) (define (split s) (let loop ((pos 0) (x delim-list) (r '())) (if (pair? x) (loop (car x) (cdr x) (cons (substring s pos (+ pos (skiptoken (shared-substring s pos) delim))) r)) (reverse r)))) (let loop ((s (gets-skip-null-line)) (r (list (split head)))) (if (eof-object? s) (reverse r) (loop (gets-skip-null-line) (cons (split s) r))))))
83 :
デフォルトの名無しさん :02/09/16 01:07
補足 (gets-skip-null-line) 空行を読み飛ばすread-line。改行コードはカットされる。 (skiptoken str delimiter) 文字列strをdelimiterで区切られたトークン列とみなし、delimiterが始まる位置を返す。 delimiterが見つからなければ(string-length str)を返す。 (skipdelimiter str delimiter) 文字列strをdelimiterで区切られたトークン列とみなし、delimiterが終わる位置を返す。 delimiterが見つからなければ0を返す。
ヘッダが無いとエラーになるのを修正。 (define (read-text-table) (var head (gets-skip-null-line) return-from exit (if (eof-object? head) (exit #f)) ...以下同じ return-fromはvarマクロの拡張構文。(varシーケンス内で使える) 書式は return-from <break-symbol> ... で、`(call/cc(lambda(,<break-symbol>)...)に変換する。 誰も使わないだろうけど、一応。
>>81 SRFI-13とSRFI-14がサポートされていれば、
(string-tokenize line (char-set-complement (char-set #\space #\tab)))
でスペースタブ区切りの行lineをフィールドのリストに分割できるよ。
gaucheだと:
(use srfi-13)
(use srfi-14)
(define (read-text-table)
(let ((delimiter (char-set-complement #[\x09 ])))
(port-map (cut string-tokenize <> delimiter) read-line)))
>>85 うわ、そんなに短くなりましたか。
なんかアホらしくなってきた・・。
でもその方法だと項目がヌル(空白)の時は上手く変換できないですよね。
↓こういうデータも入ってくる可能性があるんで・・
destination gateway flags use hopcnt expire pksent
default 192.168.0.3 BU 51551 51551
192.168.0.0/24 link#1 U
192.168.0.1 192.168.0.2 BA
(with-input-from-file "test.tbl" (read-text-table))
=>(("destination" "gateway" "flags" "use" "hopcnt" "expire" "pksent")
("default" "192.168.0.3" "BU" "51551" "" "" "51551")
("192.168.0.0/24" "link#1" "U" "" "" "" "")
("192.168.0.1" "192.168.0.2" "BA" "" "" "" ""))
ああ、それ考えるとデータの末尾の空白がヘッダカラム位置を満たしてないと
エラーになるじゃん・・バグ発見。
ちょっと修正。
;splitのcons辺り
(cons
(if (< pos (string-length s))
(substring s pos
(+ pos(skiptoken(shared-substring s pos) delim)))
"")
r))
つーか、tabの空白展開処理をまるっきりやってなかった。 行入力したらtab->space作って噛まさないと駄目だ。 もう寝よ・・。
正規表現万歳ヽ(´ー`)ノ
89 :
デフォルトの名無しさん :02/09/16 16:52
>>73 自己フォローです。デスクリプタとテーブルの概念を理解しな
ければいけませんでした。
(define zrdb (create-database "zosho.db" 'alist-table))
((((zrdb 'create-table) '*nengo-table-desc* '*columns*) 'row:insert*)
'((1 #t 年号 symbol? symbol)
(2 #f 始め #f uint)
(3 #f 終り #f uint)))
(((zrdb 'create-table) '年号テーブル '*nengo-table-desc*))
>>76 Gaucheにtraceが見つからないっす(^^;
91 :
デフォルトの名無しさん :02/09/16 17:51
これで終わったかな。 (define (tab->space str tabstop) (let loop ((r '())(spos 0)(pos 0)(tabcnt 0)) (if (< pos (string-length str)) (if (char=? (string-ref str pos) #\tab) (loop (cons (make-string (- tabstop tabcnt) #\space) (cons (shared-substring str spos pos) r)) (+ pos 1) (+ pos 1) 0) (loop r spos (+ pos 1) (if (= tabstop (+ tabcnt 1)) 0 (+ tabcnt 1)))) (apply string-append (reverse (cons (shared-substring str spos) r)))))) >(tab->space "abcdefgh\tabcde\t" 8) =>"abcdefgh abcde "
>>89 info のデバッグのとこ見てみな。trace 作ってくれてる人がいるよ。
;; trace って結構簡単に書けるもんだなって思った。
93 :
デフォルトの名無しさん :02/09/16 18:54
>>91 gaucheだとshared-substring使わなくても効率良いらしいよ。
逆にstring-set!(破壊代入系)が効率悪いらしい。
94 :
デフォルトの名無しさん :02/09/17 05:01
SCMで (symbol? '3.14159.2) が#tになったんですけど、 これはSchemeの規格通りなのですか?
95 :
デフォルトの名無しさん :02/09/17 06:57
R5RS だとそう読めるね。
R5RSに厳密に従うと、3.14159.2はシンボルとして正しくない。移植性がないというか。 <シンボル> ---> <識別子> <識別子> ---> <頭字> <後続文字>* | <特殊な識別子> <頭字> ---> <文字> | <特殊な頭字> <特殊な頭字> ---> ! | $ | % | & | * | / | : | < | = > | ? | ~ | _ | ~ <特殊な識別子> ---> + | - | ... シンボルは数字で始められません。gaucheの拡張仕様でしょう。
<文字> を忘れてた <文字> ---> a | b | c | ... | z
>>94 R5RS的には、シンボルは数字では始められない。
ただ、トークンを読んでそれが数値として認識出来れば数値に、
そうでなければシンボルにと解釈する処理系は結構ある。
Lispの方では歴史的に 1+, 1-、-1+ みたいな手続きがあるし、
SRFI-14には ->char-set という手続きが定義されているので、
処理系としては読む方は寛容に、ただし使用は推奨しないという
立場が良いんじゃなかろうか。
R5RS は 2.1. Identifires で、
>>96-98 の示すものが *少なくとも* identifire
として扱われなければならないといっている。
でも、それ以外のものを identifire として扱うことを
許容している(The precise rules for form-
ing identifires vary among implementations of Scheme, )から、
(symbol? '3.14159.2)
が #t になってもこの点では R5RS に全くもって反してはいない。
たぶん。
s/identifire/identifier/
101 :
デフォルトの名無しさん :02/09/17 19:03
aabcdef"ghij" これシンボル?
102 :
デフォルトの名無しさん :02/09/17 19:09
>>101 "は区切り文字に属してるので、aabcdefシンボル"ghij"文字列と解釈されるはず。
103 :
デフォルトの名無しさん :02/09/17 19:11
ありがとうございました では、 aabcdef#ghij や aabcdef'ghij はどうでしょう?
#,で区切られると思う。
DocBook で書かれた仕様書か処理系のマニュアルないですかね。
HTMLじゃ駄目なの?
109 :
デフォルトの名無しさん :02/09/18 17:19
ChezSchemeっていくらぐらいですか?
どうして自分で調べないんですか?
111 :
デフォルトの名無しさん :02/09/18 17:36
http://www.scheme.com/index.html ほんとだ見てきたけどChezSchemeの価格書いてないや。
関係ないけど3DSchemeのお値段。
3DScheme v2.0 [$249.95]
3DScheme Pro v2.0 [$399.95]
3DScheme Pro v2.0 (Upgrade 3DScheme v1.2/1.3) [$99.95]
EdScheme for Windows v5.0 [$149.95]
EdScheme for Windows v5.0 (Upgrade v4.3) [$49.95]
EdScheme for Windows v5.0 (Upgrade v4.0/1/2) [$69.95]
EdScheme for Windows v5.0 (Other upgrade) [$99.95]
EdScheme for Macintosh v4.0 [$79.95]
SOFTBOATみたいな日本の代理店ないのかね。
10万円ぐらいで買えそうですか?
115 :
デフォルトの名無しさん :02/09/18 21:06
たぶん買えない。
メール送ってみれば?>111
117 :
デフォルトの名無しさん :02/09/18 21:18
>>77 無名関数のトレースはtrace-lambdaつーのがあるみたいですが、どうですか?
いちいち定義書き換えるのめんどくさいかもしれない。
すみません、Lisp初心者なんですけど、無名関数で再帰するにはどうしたらいいんでしょうか? それとも、無名関数では再帰できないんですか?
>>118 lambdaだけでできるよ。
やり方は過去ログかSICP参照。
Allegro Common Lisp のお値段 Professional 414,750円 Enterprise 1,092,000円 totoで一等当たったら買ってもいいか…
>>119 どうもありがとうございます、探してきます。
122 :
デフォルトの名無しさん :02/09/18 22:55
>>118-119 これだね。
(let loop((a b)(c d))(loop e f))
↓
;lambdaだけで再帰する形
((lambda (a c)
((lambda (loop)
(loop loop a c))
(lambda (loop a c)
(loop loop e f))))
b d)
;set!を使う形
((lambda (loop)
(set! loop
(lambda (a c)
(loop e f)))
(loop b d)
'())
>>122 わざわざすみません、とても参考になります。
本当にありがとうございます。
>>120 まえに誰かが7桁って書いてたので、500万円くらいするのかと思い込んでたため、
思ってたより安いという印象を受けてしまいました。
Allegroってclispと比べてそんなによいの?
あ、ちなみに最近使い始めたpvsは評価機をAllegroインタプリタの 上で動作させてるみたいだけど、clispと比べてもの凄く巨大です。 メモリは20MBは最低でも、使い始めると40MBぐらいまで使います(笑
clisp遅っ
clispバージョン上がってましたよ、[2.30 (2002-09-15)]になってました。 すでに知ってたらスマソ。
金とって遅かったら話にならんよ。
うちの環境(P3 1GHz)で(fib 30)測ったら VC6(-O2) 120msec PetiteChezScheme 430msec 自家製scheme 18秒 (´-`).。oO(この差はなんだろう)
Javaよりもよいパフォーマンスが出るということは WebやWebサービスの仕事なんかにACLで結構いけるってことだよな。 Webサービスは最終的にはダイナミックバインディングを目指すんだろう からいよいよLispが表舞台に立てるチャンスなのかもしれない! とか妄想してみる。
やっとLispの時代がきたか…と言いたいところだが…
AllegroのWeb Server使ったみた人います?
lispache?
140 :
デフォルトの名無しさん :02/09/21 16:37
UNIXのシェルでS式使えるやつあるの?
clispをログインシェルとして使ってる猛者はいるんかなー
142 :
デフォルトの名無しさん :02/09/21 18:02
bash程度の名前補完があれば使ってもいいな
S式でシェル・・・? どんなんだろう
ls打つのにもカッコ使わないといけないから結構メンドクサソウだね。 キーバーインドを使いまくらないとだめか。
'(引用)の逆の働きがあればいいのではないかな ,ls -> (ls)
誰かclispでシェル作って…
shell> () みたいに最初から括弧が入力されてりゃ良いのでは カーソルは括弧の中
151 :
デフォルトの名無しさん :02/09/22 06:33
あの、いまアレグロのサイトみてきたんですけど、 トライアル版の期限って何回も更新できるんですね。
いい名前だな(藁 まあ、bashとかにも過敏反応してるヤシもいるが。 スレ違いだがperlのシェルってあるんかな・・・・・・
コマンドが記号だけで出来てるとか…
156 :
デフォルトの名無しさん :02/09/22 15:59
>>144 (時代に禿しく逆行してて申し訳ないが)
トップレベルを evalquote にすれば佳いのかな。
157 :
デフォルトの名無しさん :02/09/22 16:50
158 :
デフォルトの名無しさん :02/09/23 11:36
Gauche release 0.6.3 Object-apply hook に期待
161 :
デフォルトの名無しさん :02/09/24 04:29
>>160 おの説明ではいまいちわかりません。
具体的にはどう書くんですか?
162 :
デフォルトの名無しさん :02/09/24 04:31
おの→その
scshみたいなやりかたならemacsを普通に使うほうがスマートだな。 あれはそんなにいいものだとは思わない。
scsh は interactive に使うものではない。
165 :
デフォルトの名無しさん :02/09/24 12:07
じゃ、あいつ使うの?→誰?→mistake? →後戻り→じゃあ、いつ使うの?
168 :
デフォルトの名無しさん :02/09/24 19:53
>>167 え、、じゃあ他の(普通の)処理系との違いは?
169 :
デフォルトの名無しさん :02/09/24 20:43
>>168 unixのシェルスクリプトって、スクリプト自身で色々するよりも
他のコマンド同士をくっつけてゆく糊って感じでしょ。
scshにも組み込みで、パイプ使ったりリダイレクトしたりしながら
他のコマンドを呼び出しつつつなげてゆく機能がある。
プラスSchemeで中間処理も書けますよ、って感じ。
普通の処理系だと、一つのコマンドだけを呼び出すくらいなら
system()みたいなのでそんなに難しくないけど、
いくつかのコマンドをパイプでつなげたいとか、パイプラインの
途中のコマンドのエラー出力だけScheme側に取り出したいとか、
出来なくはないけれど色々コードを書かなくちゃならない。scshだと
そういうのが手軽に書ける。
。。。漏れも使ってないから、マニュアル読んで判断してるだけだけど。
(run (ls -alF) ) まあたしかに普段使うものではないな
171 :
デフォルトの名無しさん :02/09/25 05:08
>>170 意味わかりました。
ぶっちゃげるとtoplvl改造するんですね。
でも、(ls '-alF)や(exec "ls -alF")じゃだめなのかなあ
172 :
デフォルトの名無しさん :02/09/25 06:21
>>169 with-でパイプの入出力できたら面白そうだね
てめぇら、かっこつけてんじゃねぇよ
(´-`).。oO(うけると思ったんだろうな。。。)
(´-`).。oO(『かっこ』にはうるさいからなぁ。。。)
schemeダサ commonlispイイ
っていうか、lispってダサイよな。 何かいつまでたってもネイティブなexe吐かないし、lisperな教授が 殻に閉じこもってるっていう感じでかび臭いよ。 なんで実力ある奴以内の。他の言語だと1980年代なのに良くここまで深い 事欠けるって感心する人居るよな。lisperってそういうふうに外に弾け ないで内に内にと極めている雰囲気があって、ヒッキーそのものって感じ。
人 ( ´_ゝ`) ベッカムがこのスレッドに興味を示したようです
>>177 Lispって1960〜80年代なのに良くここまで深い事かけるって感心する人居るよな。
てな言語みたいよ。
>>177 どこを縦読みでつか?
マジレスすると、ネイティブへのコンパイルの話題は80年代あたりで
散々やられちゃって、もう誰も興味なくなっちゃったんじゃないか。
プロセッサの進化に合わせて行くには開発資源が要るわりに、
技術的な新鮮味があるわけじゃない。論文書きたい人は強い型付きの
関数型言語に行くだろうからね。
181 :
デフォルトの名無しさん :02/09/26 11:23
EXEみたいな単一のファイルにするのって見たこと無いな。 関数とかのパーツやモジュールをコンパイルするってのはよくあるけど、 インタプリタを捨ててまで1つのexeを吐かす必要ってのがないと 考えられてるのかな? イメージファイルとコアって組み合わせの配布形態でも作れば需要は ありそうだと思うけどねえ。 gcのマーク付けみたいな感じで必要な関数を辿っていって、そのイメージと 最小限のスタートアップを動的に生成してEXEにするのって、できそうじゃない?
183 :
デフォルトの名無しさん :02/09/26 18:09
184 :
デフォルトの名無しさん :02/09/26 18:36
どうやら キチガイがいる様ですな。
187 :
デフォルトの名無しさん :02/09/27 00:08
フリーウェアだとSIODでEXE化はできますよ。
188 :
デフォルトの名無しさん :02/09/27 23:50
継続を保存したあと、レキシカル変数を書き換えて、継続から戻ってきたら、そのレキシカル変数は書き換わったまま?でも、(+ (foo) (bar) (baz)) とかで (foo) の値とか (bar) の値とか、計算途上の値はちゃんと復元される。 つーことは、レキシカル変数と、無名の一時的な値は、保存する場所を別々にしなきゃならんのかなぁ。 実際に試したのは次のようなコードで、一見、同じでしょ?でも、実際に試したら値が変わるから。ここに来て困惑。そういうもんなの? (define (foo) (call-with-current-continuation (lambda (cc) (set! cc1 cc) 1))) (define (bar) (if cc3 (cc3 5) 2)) (define (baz) (call-with-current-continuation (lambda (cc) (set! cc3 cc) (cc1 4)))) ; その1 Petite:8 Gauche:8 (define cc1 #f) (define cc3 #f) (display (+ (foo) (bar) (baz))) ; その2 Petite:8 Gauche:11 (define cc1 #f) (define cc3 #f) (let* ((x (foo)) (y (bar)) (z (baz))) (display (+ x y z))) ; その3 Petite:11 Gauche:11 (define cc1 #f) (define cc3 #f) (let ((x 0) (y 0) (z 0)) (set! x (foo)) (set! y (bar)) (set! z (baz)) (display (+ x y z)))
189 :
デフォルトの名無しさん :02/09/28 00:52
>>188 処理系のバインドのタイミングの違い。
その1はdisplay関数の引数評価中に副作用を起こしてるので結果は不定、
その2はlet*のフレームの生成の途中で継続が呼び出されるから、これも
処理系依存。こういった継続呼び出しの対策がされてない処理系では
環境がクラッシュするかもね(w
その3はフレームの生成が終わった後なのでうまく処理できるんだと思う。
そうか・・・不定・・・処理系依存・・・気にしなくていいのか、素晴らしい!(何が) クラッシュしたりもするんだ。へぇぇ。 どうもありがとう。参考になった!
schemeショボイ
コモンリスプ萌え
193 :
デフォルトの名無しさん :02/09/30 22:02
ACLほすぃな〜
漏れもACLほすぃ 恵んでくれ
195 :
デフォルトの名無しさん :02/09/30 23:36
cmuclで我慢汁
clispで我慢中
カコイイ GUI が使えるのは windows 版だけ?
>>198 カコイイかどうかはともかく、DLL叩ける処理系ならGUI作れると思うよ
それとも「使える」ってのはIDEみたいな開発環境のこと?
201 :
デフォルトの名無しさん :02/10/03 05:52
204 :
デフォルトの名無しさん :02/10/03 09:19
>>203 組みこみなのが萎える。
どうせならschemeでリーダ書いて汎用化してほしい。
205 :
デフォルトの名無しさん :02/10/03 13:09
ちと、スレ違いっぽい気がするんですが、書き込んじゃいます。 AppleがDylanを開発したときのエピソードですけれど。 Appleが研究開発部門を統合することになって、 使用言語を統一したいって話になったんだそうな。 統合される前の各チームはObject Pascalだったり C++だったり、Common Lispだったりしたんだと。 で、一番機能があるのはCommon Lispなんで、 Common Lispに統一するか、って話になったんだけど、 「配布はどうするよ」って問題が出てきた、と。 で、Common Lisp並みのパワーがあって、配布の容易な 実行形式を生成できる言語を作ろうって話になり、 Dylanが作られたって話が伝わってる。 Dylanにはマクロがあって、当時は「マクロがあること がそんなに大事なの?」みたいに思ってたけど、Lispを 学んだあとだと、必要だよなあって思う。 で、Dylanは日の目を見なかったんだけど、なにやらPythonに Dylan譲りのマクロが組み込まれるかも、みたいな話を読んで、 何?とか思ったので、書き込みたくなりました。 駄文でスマン。
>>205 そこでCommon Lispに走っていれば,今頃うふふだったのにね
207 :
デフォルトの名無しさん :02/10/03 19:53
dylanのマクロってどんなの?
208 :
デフォルトの名無しさん :02/10/04 10:14
211 :
デフォルトの名無しさん :02/10/05 02:37
最近、LispおよびSchemeを学習したいと思っているんだけど、 どの処理系に手をつけていいのかわからない。 オススメあったら教えてください。環境はWindows 2000で出来ればcygwin依存じゃないやつ。 学習用だから、手軽なのでいいけど、できれば実用的であればなおよし。シャッス。
シャッス。
DrScheme
xyzzy
acl
cmu
On Lisp はいつまでたっても在庫切れだ…
>>211 実用をもとめるならEmacsとかから初める物なのかもしれず。
とっかかりやすいですから。
EmacsにはまるのがLisp学習一番はやい気がする。
>>220 同意。
一からプログラムつくるより成果が得やすくて役に立つので、
意欲が出やすいというかはまりやすいというのもあるかも知れません。
スキルのあるやつは、いきなり自作から入ってどっぷり漬かるのも いいとおもうよ。
223 :
デフォルトの名無しさん :02/10/06 13:05
DrSchemeをWinXPProにインストールしようとしたところ、コマンドプロンプトが出てきてしばらくすると、たいてい同じタイミングでいつもフリーズ。 同じような症状出た人います?情報&解決案キボンヌ!!
224 :
デフォルトの名無しさん :02/10/06 17:42
Gaucheでは下のようなことができます。 (tree->string (html:h1 "はじめに")) => "<h1>はじめに</h1>\n" 次の式は思うように評価できません。どこがおかしいのでしょうか? (tree->string (append '(html:h1) '("はじめに"))) =>"html:h1はじめに"
225 :
デフォルトの名無しさん :02/10/06 19:21
html:h1 って手続きじゃない?
その場合は eval を使わないといけないんじゃ? (tree->string (eval (append '(html:h1) '("はじめに")))) って感じで。
(tree->string (eval (list 'html:h1 "はじめに")))
eval は2引数でしょ。
229 :
デフォルトの名無しさん :02/10/06 23:44
windowsでLispを始めたいけど、Emacs系ユーザじゃないからナカナカ切っ掛けがつかめないんです。 ちなみに常用しているエディタはVimッス。シャッス。
230 :
デフォルトの名無しさん :02/10/06 23:47
>>225 -
>>228 ありがとうございます。Gauche的にはevalは2引数ですね。
(tree->string (eval (append '(html:h1) '("はじめに"))(interaction-environment))
でもなぜevalしなきゃいけないのでしょうか? appendした段階
でリストはできているのですが。
(append '(html:h1) '("はじめに"))と(html:h1 "はじめに")は
ちがうんですか?
>(+ 1 1) 2 >'(+ 1 1) (+ 1 1)
232 :
デフォルトの名無しさん :02/10/07 01:31
こんなのできましたけど、もっと簡単になりますか? (tree->string (eval (append '(html:tr) (list (append '(html:td) '("はじめに"))))(interaction-environment) )
(tree->string (html:tr (html:td "はじめに"))) ではダメな理由でもあるの?
quoteの概念をまず学んだほうが良い気がする
235 :
デフォルトの名無しさん :02/10/07 01:55
>>233 あっ、そうですね。関数を作ってたら、どんどん理解
できなくなっていました。ご指摘、ありがとうございます。
でも今度はevalがなくても希望どおり動く。まだ理解できていません。
>>234 基本がわかってないんですよね、私。
(define (hoge one two)
(tree->string (html:tr (html:td one) (html:td two))))
=>hoge
(hoge '山田 '太郎)
=>"<tr><td>山田</td>\n<td>太郎</td>\n</tr>\n"
236 :
デフォルトの名無しさん :02/10/07 02:04
> 基本がわかってないんですよね、私。 「基本からわかってないんですね、私」に訂正します (^^;
schemeではよっぽどの事がない限りはeval関数を使う必要ないよ
>>235 Gaucheの組みこみ関数知らないんで間違ってるかもしれないけど、
html:trが可変引数取れるなら、
(define (hoge . args)
(tree->string(apply html:tr(map html:td args)))
と書いたらスマートだよ。
たぶん。
(hoge '山田 '太郎 '花子 ...)
=>"<tr><td>山田</td>\n<td>太郎</td>\n<td>花子</td>\n...</tr>\n"
ちなみに (define (hoge . args)...) は (define hoge(lambda args ...)) と同じだから。 これをふまえると、list関数は (define (list . args)args) で定義できる。 (list 'hoge 1 2 3 "a b") =>(list hoge 1 2 3 "a b") 同様にstringも、 (define (string . args)(list->string args))
評価の仕組みがわかってないような。 リストとリストを評価したものは別物ですよ。 (tree->string (html:h1 "はじめに")) で、(html:h1 "はじめに")っていうリストを tree->stringに渡してるって思っていない? トップレベルで (html:h1 "はじめに") を入力してみて。 ("<h1>" "はじめに" "</h1>" "\n") みたいなのが返ってくるんじゃないかな。 手続きの引数は評価されるので、この後の方のリストが渡されるんです。
>>229 だったらEmacsつかいになれば?
きっかけないと学べないならどうせ学べない。
emacs使ってないけどLISPわかりますが何か。 emacsも使えるけどね。
243 :
デフォルトの名無しさん :02/10/07 08:38
>>240 あたりです。もっともモヤモヤしているところです。じっくり理解に
努めてみます。ありがとうございます。
244 :
デフォルトの名無しさん :02/10/07 08:41
>>238 あっ、これ本で見たことあります。こういうところで使えばいいの
ですね。(本の中とプログラミングの中では、違うように見えます、
私)
>>238 「組み込み関数」という言い方にあなたの(コミュニティの)年齢を感じた。
>>245 組み込み=ビルトイン
って意味だけど、なんか変?
組み込み手続き?
うちの gauche が日本語通らなくなってると思ったら公式 deb のやつ utf-8 だったよ…。 source から入れることにしよ。
>>246 system供給関数を全部「組み込み」と呼ぶ人がいた。
今は組み込みっていうと、
The Free On-line Dictionary of Computing (09 FEB 02)より
built-in:
(Or "primitive") A built-in function or operator is one
provided by the lowest level of a language implementation.
This usually means it is not possible (or efficient) to
express it in the language itself. Typical examples are the
basic arithmetic and {Boolean} operators (in {C} syntax: +, -,
*, /, %, !, &&, ||), bit manipulation operators (~, &, |, ^)
and I/O primitives. Other common functions may be provided in
libraries but are not built-in if they are written in the
language being implemented.
って感じ。Lisp 1.5でいうところの"(f)subr"のこと。
どうでもいいsage
Windows上、フリーで使えるCLOS環境ってある? Cygwinもあるんだけど。
>>250 windows free CLOSで検索してみんしゃい
CLOSはANSI Common Lispの仕様に含まれているから、 ANSI Common Lisp準拠のCommon Lisp実装ならば CLOSが利用可能なはず。 Clispでも使えるんじゃないかな。
>>251 スマソ。お勧めとか聞きたかったんだが書き間違えますた。
>>252 Clisp入れますた。別のマシンにはCMU Lispっての入れてみました。
254 :
デフォルトの名無しさん :02/10/09 15:29
Clispの終了コマンドは何ですか?
255 :
デフォルトの名無しさん :02/10/09 15:30
(quit)
(´-`).。oO(こんなアフォな質問に答えなくていいよ。。。)
「コマンド」とか言ってる時点で素人
258 :
デフォルトの名無しさん :02/10/09 18:41
貴様等オレよりちっとはLispでプログラムできるからって 偉そうにしてんじゃねーぞ、ヴォケ そんなにできるんだったらOSでもLispで作ってみろや
そんなことよりさ、ソース書いていいソフト作ろうよ。
いまだにLispを終了するときのコマンドが (bye) だと思っている漏れは逝ってよしですか?
263 :
デフォルトの名無しさん :02/10/10 06:22
(シュワちゃん) =>コマンドー
264 :
デフォルトの名無しさん :02/10/10 14:20
lambdaだけのfib ((lambda(i)((lambda(l)(l l i))(lambda(l i) (if(< i 2)n(+(l l(- i 1))(l l(- i 2)))))))30) =>832040 理屈はわかるけど不思議な感じ。
265 :
デフォルトの名無しさん :02/10/10 14:20
間違えた。 ((lambda(i)((lambda(l)(l l i))(lambda(l i) (if(< i 2)i(+(l l(- i 1))(l l(- i 2)))))))30)
Common Lisp の loop って何か気持ち悪いね。括弧がなさすぎて(w
lambdaだけのループをテンプレート化してみました。 書式はnamed-letと同じ。 (define-macro (lambda-loop loop var . body) `((lambda ,(map car var) ((lambda (l) (l l ,@(map car var))) (lambda (,loop ,@(map car var)) ((lambda(,loop) ,@body )(lambda ,(map car var) (,loop ,loop ,@(map car var)))) ))),@(map cadr var))) ;テスト (lambda-loop loop ((a 0)) (cond ((< a 10) (display a)(newline)(loop(+ a 1))) (else #t))) 0 1 2 3 4 5 6 7 8 9 =>#t
無駄な部分があったので修正。 (define-macro (lambda-loop loop var . body) `((lambda (,loop) (,loop ,loop ,@(map cadr var))) (lambda (,loop ,@(map car var)) ((lambda(,loop),@body) (lambda ,(map car var) (,loop ,loop ,@(map car var)))))))
これはnamed-letとどう違うんだ?
先程のfibを書き直すと、 (lambda-loop loop ((i 30)) (if(< i 2)i(+ (loop (- i 1))(loop (- i 2))))) 展開すると、 ((lambda (loop) (loop loop 20)) (lambda (loop i) ((lambda (loop) (if(< i 2)i(+ (loop (- i 1))(loop (- i 2))))) (lambda (i) (loop loop i)))))
>>269 named-letと同じです。
末尾再帰もちゃんとします。
違うのは作りだけです。(普通set!を使う)
あー、
>>270 のインデントがおかしかったので、もう一度。
先程のfibを書き直すと、
(lambda-loop loop ((i 30))
(if(< i 2)i(+ (loop (- i 1))(loop (- i 2)))))
展開すると、
((lambda (loop) (loop loop 30))
(lambda (loop i)
((lambda (loop)
(if(< i 2)i(+ (loop (- i 1))(loop (- i 2)))))
(lambda (i) (loop loop i)))))
これを踏まえると、letrecもlambdaだけで作れそうです。
lambda=ランバダ でいいですか?
ラムダ、Λ、λ。
>>274 純粋にlambdaだけでnamed-letとかletrecを定義できるのか?
というのを考えてました。
そのリンク先のは、目的が微妙にズレてますね。
fixとかいう文法をでっち上げて逃げてるのかな?
何をprimitiveに選ぶかの違いかな。 lambdaだけで再帰関数を書くとlambdaが溢れるけど、fixだと (fix ((loop (i) (if(< i 2)i(+ (loop (- i 1))(loop (- i 2)))))) (loop 20)) で済む。 fixもlambdaだけで書けると思うけど。
279 :
デフォルトの名無しさん :02/10/10 18:27
letrecは無理っぽいぞ
280 :
デフォルトの名無しさん :02/10/10 18:29
つーかnamed-letモドキが出来ただけでも驚異的な気がする
>>278 fixの方だと、別にletも必要みたいです。
あっちはコンパイラを作ってるみたいなので、目指す所も違うかと。
>>279 テンプレート化可能かは判りませんが、作れそうですよ。
例えば gauche のようにバイトコードに変換する処理系というのは C での実 装レベルでどのような処理を行なっているんでしょうか? gauche のソースは眺めてみたんですがよく分からないので。 例えば SICP の 4章にあるような最適化を行なうことなんでしょうか。 でもバイトコードって感じじゃないから多分違うかな…
>>281 letrec は R5RS によると
(letrec ((even? (lambda (n) (if (zero? n) #t (odd? (- n 1)))))
(odd? (lambda (n) (if (zero? n) #f (even? (- n 1))))))
(even? 88))
は大体こういう風に展開されるね。
((lambda (even? odd?)
((lambda (temp1 temp2)
(set! even? temp1)
(set! odd? temp2)
(even? 88))
(lambda (n) (if (zero? n) #t (odd? (- n 1))))
(lambda (n) (if (zero? n) #f (even? (- n 1))))))
'<undefined> '<undefined>)
even? と odd? の評価順序を一緒にしなければならないところが難しい気がする。
let* みたいに順番に評価してもいいなら結構楽だと思う。
>>284 読みました。でも理解できてないです。
minischeme みたいなのはだいたい理解できるんですが。VM っていうのは未知
の世界ですね。アセンブラの勉強した方がいいのかな。(スレ違いっぽいけど)
どんな本読んだらいいんだろ。推薦図書スレ覗いてきます。
>>285 スタックマシンみたいな簡単な例で説明すると
(+ (- 2 1) 2)という式なら、
ldc 2
ldc 1
ldc 2
ldg -
apply
ldg +
tail-apply
と言う様に、構文解析をしなくて良い形に直したもの、
って認識でいいんじゃないかと。
上のオペレータの補足
ldc:load const
ldg:load global
apply:評価
tail-apply:末尾評価(スタックフレームの保存を行わない)
参考書はコンパイラの本とか。
つーか仕様書読めばのってるぞ 派生式をlambda式に展開するのは
>>281 こんな感じでどうだろう。
とりあえず、結果は合ってるみたいだけど…
(letrec-syntax
((lambda-letrec
(syntax-rules ()
((_ "expand" (sym ...) (lambda (arg ...) . body))
(lambda (arg ...)
((lambda (sym ... arg ...) . body)
sym ... arg ...)))
((_ "expand" (sym ...) val) val)
((_ ((sym val) ...) . body)
((lambda (sym ...) . body)
(lambda-letrec "expand" (sym ...) val) ...)))))
(lambda-letrec ((even? (lambda (n)
(if (= n 0) #t
(odd? (- n 1)))))
(odd? (lambda (n)
(if (= n 0) #f
(even? (- n 1))))))
(even? 88)))
>>288 ぐあ…ダメそう…
組み込みの odd? と even? 呼んでるよ…
作り直してみる…
(letrec-syntax ((lambda-letrec (syntax-rules () ((_ "do" ((fsym def) ...) ((sym val) ...) loop . body) ((lambda (l) (l l #f)) (lambda (loop func . args) ((lambda (fsym ...) ((lambda (sym ...) (cond ((not func) . body) ((equal? func (quote fsym)) (apply fsym args)) ...)) val ...)) def ...)))) ((_ "extract" ((sym1 (lambda args . defs)) . rest) (extracted ...) all loop . body) (lambda-letrec "extract" rest (extracted ... (sym1 (lambda args (loop loop (quote sym1) . args)))) all loop . body)) ((_ "extract" () . body) (lambda-letrec "do" . body)) ((_ "extract" ((sym val) . rest) . body) (lambda-letrec "extract" rest . body)) ((_ bindings . body) (lambda-letrec "extract" bindings () bindings loop . body))))) (lambda-letrec ((even (lambda (n) (if (= n 0) #t (odd (- n 1))))) (odd (lambda (n) (if (= n 0) #f (even (- n 1)))))) (even 89)))
でこれはどう展開されるのかね。
293 :
デフォルトの名無しさん :02/10/11 09:00
なんか面白い事やってるね。
>>288 ,
>>290 多分、letrec-syntaxを使ってる限り無駄なんじゃないかと思う。
lambdaのみで展開される保証はないし。
>>264 みたいに、まずlambdaだけの仮組みを作らないと。
とりあえず… lambda だけだと、ここまではできた。 ((lambda (even odd) ((lambda (even odd) (even 88)) (even even odd) (odd even odd))) (lambda (even odd) ((lambda (even odd) (lambda (n) (if (= n 0) #t (odd (- n 1))))) (lambda (n) ((even even odd) n)) (lambda (n) ((odd even odd) n)))) (lambda (even odd) ((lambda (even odd) (lambda (n) (if (= n 0) #f (even (- n 1))))) (lambda (n) ((even even odd) n)) (lambda (n) ((odd even odd) n))))) =>#t
>>294 素晴らしいですね。
私も作ってましたが、ほとんど同じ物になりました。
このパターン以外はできないかな?
((lambda (even? odd?)
((lambda (even? odd?)(odd? 10))
(even? even? odd?) (odd? even? odd?)))
(lambda (even? odd?)
((lambda(even? odd?) (lambda (x) (if (= x 0) #t (odd? (- x 1)))))
(lambda args (apply (even? even? odd?) args))
(lambda args (apply (odd? even? odd?) args))))
(lambda (even? odd?)
((lambda(even? odd?) (lambda (x) (if (= x 0) #f (even? (- x 1)))))
(lambda args (apply (even? even? odd?) args))
(lambda args (apply (odd? even? odd?) args)))))
ここまでできると、テンプレート化は簡単でした。 ;lambdaだけのletrec (define-macro (lambda-letrec var . body) (let ((mcv (map car var))(args (gensym))) `((lambda ,mcv ((lambda ,mcv ,@body) ,@(map (lambda (x) (cons (car x) mcv)) var))) ,@(map (lambda(x) `(lambda ,mcv ((lambda ,mcv ,(cadr x)) ,@(map (lambda (x) `(lambda ,args (apply (,(car x) ,@mcv) ,args))) var)))) var))))
こういう相互末尾再帰もちゃんと機能します。 (lambda-letrec ((a(lambda(x)(b(+ x 1)))))) (b(lambda(x)(c(+ x 1)))))) (c(lambda(x)(a(+ x 1))))))) (a 0))
間違えた・・ (lambda-letrec ((a(lambda(x)(b(+ x 1)))) (b(lambda(x)(c(+ x 1)))) (c(lambda(x)(a(+ x 1))))) (a 0)) ↓展開結果 ((lambda (a b c) ((lambda (a b c) (a 0)) (a a b c) (b a b c) (c a b c))) (lambda (a b c) ((lambda (a b c) (lambda (x) (b (+ x 1)))) (lambda g149 (apply (a a b c) g149)) (lambda g149 (apply (b a b c) g149)) (lambda g149 (apply (c a b c) g149)))) (lambda (a b c) ((lambda (a b c) (lambda (x) (c (+ x 1)))) (lambda g149 (apply (a a b c) g149)) (lambda g149 (apply (b a b c) g149)) (lambda g149 (apply (c a b c) g149)))) (lambda (a b c) ((lambda (a b c) (lambda (x) (a (+ x 1)))) (lambda g149 (apply (a a b c) g149)) (lambda g149 (apply (b a b c) g149)) (lambda g149 (apply (c a b c) g149)))))
set!が無い代わりに、applyが入ってるのが納得いきませんが、 letrecに渡される関数引数が事前にわからないので、 これ以上どうしようもありませんでした。 (以前に出てきたリンク先のfixの様に、文法を変形すれば applyを無くす事も可能ですけど。)
自力で lambda 式を解析して、 apply 外してみた。 ついでに、普通の変数の混在もできるように。 (defmacro (lambda-letrec var . body) (let* ((mcv (map car var)) (separate (let loop ((x var) (f '()) (v '())) (cond ((null? x) (cons (reverse f) (reverse v))) ((and (pair? (cadar x)) (equal? (caadar x) 'lambda)) (loop (cdr x) (cons (car x) f) v)) (else (loop (cdr x) f (cons (car x) v)))))) (funcs (car separate)) (vars (cdr separate)) (mcf (map car funcs))) `((lambda ,mcf ((lambda ,mcv ,@body) ,@(map (lambda (x) (cons x mcf)) mcf) ,@(map cadr vars))) ,@(map (lambda (mfun) `(lambda ,mcf ((lambda ,mcf ,(cadr mfun)) ,@(map (lambda (mfun1) (let ((args (cadr (cadr mfun1)))) `(lambda ,args ((,(car mfun1) ,@mcf) ,@args)))) funcs)))) funcs))))
レス遅くなりましたが…。
>>286 ありがとうございます。
わかったようなわからないような、ですけど。イメージはつかめたので後は自
力でソース読めるようになるまで修行します。
>>292 英語でもいいですよ。英語なら良い本 or 資料があるんですか? 英語の勉強
もかねて SICP や ANSI Common Lisp は原書で読んでいるので、それほど難し
くなければ読めます。
えっと…
>>300 の bug を二つ潰したんだけど…
流石にしつこいかな?
303 :
デフォルトの名無しさん :02/10/12 14:01
割り込みスマソ。 Schemeってput/getってあるの? DBに手続きをぶちこむ感じの手続きなんだけど。
304 :
デフォルトの名無しさん :02/10/12 14:32
>>302 ぜひやってくれ。俺にはさっぱり理解できぬ領域だが。
>>303 仕様書には載ってないけど、処理系によっては用意されてると思うよ。
昔ながらのget/put作って、自分で(シンボル . 値)のテーブル作って
ぶちこんどけば?(SICPにまるっきり同じ例があるよ。)
(defmacro (lambda-letrec var . body) (let* ((separate (let loop ((x var) (f '()) (v '())) (cond ((null? x) (cons (reverse f) (reverse v))) ((and (pair? (cadar x)) (equal? (caadar x) 'lambda)) (loop (cdr x) (cons (car x) f) v)) (else (loop (cdr x) f (cons (car x) v)))))) (funcs (car separate)) (vars (cdr separate)) (mcf (map car funcs)) (narg (lambda (args) (let loop ((rest args) (new ())) (if (pair? rest) (loop (cdr rest) (cons (car rest) new)) (reverse (if (null? rest) new (cons rest new)))))))) `((lambda ,(map car vars) ((lambda ,mcf ((lambda ,mcf ,@body) ,@(map (lambda (x) (cons x mcf)) mcf))) ,@(map (lambda (def) `(lambda ,mcf ((lambda ,mcf (lambda ,(narg (cadr def)) ,@(cddr def))) ,@(map (lambda (mfun) (let ((args (cadr (cadr mfun)))) `(lambda ,args ((,(car mfun) ,@mcf) ,@(narg args))))) funcs)))) (map cadr funcs)))) ,@(map cadr vars))))
大文字小文字を区別する Common Lisp の処理系ってある? マニュアル読んだら Allegro Common Lisp の mlisp はそうらしいんだけど、 それ以外で。
(defmacro (lambda-letrec var . body) (let* ((separate (let loop ((x var) (f '()) (v '())) (cond ((null? x) (cons (reverse f) (reverse v))) ((and (pair? (cadar x)) (equal? (caadar x) 'lambda)) (loop (cdr x) (cons (car x) f) v)) (else (loop (cdr x) f (cons (car x) v)))))) (funcs (car separate)) (vars (cdr separate)) (mcf (map car funcs)) (narg (lambda (args) (let loop ((rest args) (new ())) (if (pair? rest) (loop (cdr rest) (cons (car rest) new)) (reverse (if (null? rest) new (cons rest new)))))))) `((lambda ,(map car vars) ,(map (lambda (def) `(lambda ,mcf ((lambda ,mcf ,@def) ,@(map (lambda (mfun) (let ((args (cadr (cadr mfun)))) `(lambda ,args ((,(car mfun) ,@mcf) ,@(narg args))))) funcs)))) `(,body ,@(map (lambda (def) `((lambda ,(narg (cadr def)) ,@(cddr def)))) (map cadr funcs))))) ,@(map cadr vars))))
>>307 の変更点
・変数の有効範囲を修正
・可変個の引数に対応
(lambda-letrec ((pr (lambda args (apply print min args)))
(min 1))
(pr)
(set! min 2)
(pr))
こんなのが
((lambda (min)
((lambda (pr)
((lambda (pr) (pr) (set! min 2) (pr))
(lambda args ((pr pr) args))))
(lambda (pr)
((lambda (pr)
(lambda (args)
(apply print min args)))
(lambda args ((pr pr) args))))))
1)
こんな感じに。
schemeがcommonlispより優れている点って何?
311 :
デフォルトの名無しさん :02/10/13 09:13
>>306 |Symbol|
という書式で大文字小文字の区別は保存されると思うけど。
>>309 そんなもん無いよ。
schemeの方がシンプルってぐらいだにょ
313 :
デフォルトの名無しさん :02/10/13 20:33
とりあえずWindows2000上で動きSetup.exeで簡単にインストール
できるSchemeがほしかったのです.
ftp://ftp.pasteur.fr/ pub/computing/Scheme/STk/Binary/STkwin32-4.0.1.zip
にあったからいいですけどプロジェクトがなくなっていたらこの後の
versionも期待できないしなあ...
DrSchemeは?
316 :
デフォルトの名無しさん :02/10/14 08:35
内部定義の振るまいについて質問なんですが、 (define (a x y z) (define (x)(display 'x)(newline)(y)) (define (y)(display 'y)(newline)(z)) (define (z)(display 'z)(newline)(x)) (x)) これは、 (define (a x y z) (letrec ((x (lambda()(display 'x)(newline)(y))) (y (lambda()(display 'y)(newline)(z))) (z (lambda()(display 'z)(newline)(x)))) (x))) これと同じなんですよね? とすると、aの引数のx y zは見えなくなるということで いいんでしょうか?
317 :
デフォルトの名無しさん :02/10/14 08:41
さらに、↑が真だとすると、 (define (a x y z) (define x y) (define y z) (define z x) (x)) これはどうなるんでしょうか?
318 :
デフォルトの名無しさん :02/10/14 08:43
(define (a x y z) (let* ((x y) (y z) (z x)) (x)))
319 :
デフォルトの名無しさん :02/10/14 08:48
>>318 ありがとうございます。
すると、
>>316 ,
>>317 が組み合わさった場合、
(define (a x y z)
(define x y)
(define (y) (z))
(define (z) (x))
(x))
こんなケースはどんなことになるんでしょうか?
321 :
デフォルトの名無しさん :02/10/14 08:53
(define (a x y z) (let ((x y)) (letrec ((y (lambda()(z))(z (lambda()(x)))) (x))) になる?
322 :
デフォルトの名無しさん :02/10/14 08:54
>>320 今使ってる処理系が正しいとは限らないので
323 :
デフォルトの名無しさん :02/10/14 08:55
>>321 (define (a x y z)
(letrec ((x y)(y (lambda()(z))(z (lambda()(x))))
(x))
だとおかしくなるから、それでいいかと。
補足すると、
>>323 をlambdaに変換すると、
(define (a x y z)
((lambda (x y z)
(set! x y)
(set! y (lambda () (z)))
(set! z (lambda () (x)))
(x))
'() '() '()))
こうなるから、期待通りに走らない。
325 :
316ですが、 :02/10/14 09:06
まとめると、内部定義で (define name value)のパターンはletへ (define name (lambda 〜))のパターンはletrecへ 変換するということでいんでしょうか。 バイトコードに変換する過程を作ってるんですが、 この辺がシビアなので困ってました。 ありがとうございました。
let とか let* に変換されるべきなの?
Just as for the equivalent `letrec' expression, it must be possible to
evaluate each <expression> of every internal definition in a <body>
without assigning or referring to the value of any <variable> being
defined.
ってあるから、「期待通りに走らない」方が正しそうな気がするけど…
; でも、そうすると
>>307 にはまだ bug が…
インタプリタだとシンボルでアクセスできてたものが、 バイトコードで相対値に変わるから、思わぬ罠にはまるってやつ? internal-defineをそのまま変換しようとすると、cdr方向に 変数スタックが伸びていくから結構厄介かもな。 (letやletrecはcar方向)
329 :
デフォルトの名無しさん :02/10/14 09:40
「内部定義がletrecに変換される」という仮定は正しいの?
330 :
デフォルトの名無しさん :02/10/14 09:44
>>325 内部定義で
(define name (let (...)(lambda ...)))
とされた場合は?
331 :
デフォルトの名無しさん :02/10/14 09:47
(let (...) (letrec (...)
333 :
デフォルトの名無しさん :02/10/14 10:12
>>331 やるなら(letrec ((name (let (...) (lambda ...)))) 〜)
でしょ。でも、これ
>>325 の方法で判定するのって大変な気が。
とはいえ、
(define (a x y z)(define x y)〜)
はletに変換されて欲しいケド
(define (a x y z)(let ((x y))〜))
とにかく、
(define name value)
この時点でvalueは関数か否か、を判定するのは大変だよ。
擬似evalでも作らないと。
>>317 エラー
>>329 R5RSに書いてあるよ。
> 内部での定義を含む<ボディ>は、完全に等価なletrec式に必ず変換できる。例えば上記のlet式は次の式に等価である。
> まさに等価なletrec式の場合と同じく<ボディ>内部での定義の<式>は、定義中のいかなる<変数>への割り当ても参照も行なわずに、一つ一つ評価できなければならない。
何気に書いてみたら >326 に同じこと書いてあった・・・
336 :
デフォルトの名無しさん :02/10/14 13:26
なんだ letrecでいいのか。
337 :
デフォルトの名無しさん :02/10/14 13:40
petite-schemeで試したら (define (a x y z) (letrec ((x y) (y (lambda()(display 'y)(z))) (z (lambda()(display 'z)(x)))) (x))) (define (a x y z) (define x y) (define (y)(display 'y) (z)) (define (z)(display 'z) (x)) (x)) 両方とも無限ループになった。 (a 1 2 3) yzyzyzyzyz........
338 :
デフォルトの名無しさん :02/10/14 13:44
ということは、
>>324 の変換じゃ駄目ということか?
339 :
デフォルトの名無しさん :02/10/14 13:46
340 :
デフォルトの名無しさん :02/10/14 14:21
引数を逆向きにしても動作するってことは、 petite-schemeのletrecの実装はインテリジェントなやつか、 lambda-letrecの様な処理を入れてるっぽい。
341 :
デフォルトの名無しさん :02/10/14 14:52
ほう
342 :
デフォルトの名無しさん :02/10/14 16:28
内部定義が連続してない場合はどうなるの? (define (a x y z) (define x y) (set! x z) ;このzはどう考えてもaの引数のやつだよなあ (define (y)(display 'y) (z)) (define (z)(display 'z) (x)) (x)) とか。 こういう風には書けなかったっけ。
343 :
デフォルトの名無しさん :02/10/14 16:39
>>342 Petite Chez Scheme Version 6.0a
Copyright (c) 1998 Cadence Research Systems
> (define (a x y z)
(define x y)
(set! x z)
(define (y)(display 'y) (z))
(define (z)(display 'z) (x))
(x))
Error: invalid context for definition (define (y) (display (quote y)) (z)).
Type (debug) to enter the debugger.
>
344 :
デフォルトの名無しさん :02/10/14 17:00
>>340 結果が違うから、少なくともlambda-letrecとは違う実装。
(define (a x y z)
(letrec ((x y)
(y (lambda()(display 'y)(z )))
(z (lambda()(display 'z)(x ))))
(set! x z)
(x)))
(a 1 2 3)
zzzzzzzzzzzzzzzzz.....
(define (a x y z)
(lambda-letrec ((x y)
(y (lambda()(display 'y) (z )))
(z (lambda()(display 'z)) (x ))))
(set! x z) ;スコープが違うので効果無し
(x)))
(a 1 2 3)
zyzyzyzyzyzyzyzyzy.....
つーか普通前者だが
348 :
デフォルトの名無しさん :02/10/17 15:19
Kawaってどれぐらい速いの?
349 :
デフォルトの名無しさん :02/10/17 20:31
質問です。slibのデータベースを使っています。下はOKでした。 (define zrdb (create-database "file.db" 'alist-table)) (define a-desc-creator ((zrdb 'create-table) 'aデスク '*columns*)) (define b-desc-creator ((zrdb 'create-table) 'bデスク '*columns*)) でも、一端dbを閉じるとだめです。これでは、テーブルを追加できないの で、困っています。何か問題があるのでしょうか? (define zrdb (create-database "file.db" 'alist-table)) (define a-desc-creator ((zrdb 'create-table) 'aデスク '*columns*)) ((zrdb 'close-database)) (define zrdb (open-database! "file.db")) (define b-desc-creator ((zrdb 'create-table) 'bデスク '*columns*)) --->*** ERROR: bad procedure: #f --->Stack Trace:
351 :
デフォルトの名無しさん :02/10/17 22:28
>>349 これは、クローズの後でオープンができていないためでした。
(define zrdb (open-database! "file.db"))
zrdb =>f
なぜオープンてきないのでしょうか。
>>350 ほー意外に速そうですね。
型をある程度特定すればJavaに追いつくのかな?
>>349 つーか、ソースあるんだから根本のエラーになってる個所ぐらいは
自分で特定できない?
処理系はGaucheだろうけど、デバッガ無いの?
>>351 漏れのところじゃ動くけど… (Gauche 0.6.4, slib 2d4, Linux 2.4)
355 :
デフォルトの名無しさん :02/10/18 20:26
ACL、日本語の扱い、デフォルトできちんとできるんだね。 ちと感心した。
cmucl で日本語通るようにする tips ってリンク切れなんだけど知ってる人い たら教えて。
357 :
デフォルトの名無しさん :02/10/19 12:08
>>356 tipsってことは、日本語パッチとかじゃないの?
358 :
デフォルトの名無しさん :02/10/19 16:57
359 :
デフォルトの名無しさん :02/10/19 21:24
>>355 そりゃ日本でも売ろうとしてるんだから、できなきゃヤバイでしょ。
360 :
デフォルトの名無しさん :02/10/22 14:52
大学の授業でLISPをやり始めたのですが、開始2週にしてギブアップしたくなって しまいました。ここの皆さんならこんな課題1分で終わりますか?正直、お手上げ です。もしよかったら教えてください。 課題1 コード 65 66 67 … 90 文字 A B C … Z 上の表を連想リストで表しなさい。 また、コードを文字に、変換する関数code-to-charを作れ。また、文字をコードに 変換する関数char-to-codeを作れ。 課題2 再帰的関数定義の方法を用いて、任意の個数の英数字、もしくは数値としての文字 コードからなるリストを受け付け、それらを各々文字コード、英数字に変換する関 数recursive-transferを作りなさい。 (例:リストが (73 l 76 v 69) ならば出力は (i 76 o 86 e)となるような関数) 課題3 dolistをもちいて、課題2と同様な機能を持つ関数dolist-transferを作りなさい。 課題4 リストの深さによらず要素を逆順にする関数reverse-allを作りなさい。
○投げか…
宿題スレに行け。 # 大学生のくせにこんな簡単なのすら出来ないんかい……
363 :
デフォルトの名無しさん :02/10/22 21:26
set! はどうして値を返してくれないの? 破壊的なやつはなるべく使うな、ってこと? でも 2D な vector とかでは破壊していく以外に考えられないよぅ。
>>363 値を返してくれないんじゃなくて、返り値が未定義なんじゃなかった?
それはいいとして、set! にどんな値を返してほしいの?
表示的意味を明確にできるように追求した結果、 つーことでしょう。知らんけど。
363じゃないけど、例えば (set! a 1) が 1 を返してくれると Tcl みたいに (set! c (set! b (set! a 1))) とかできるね。 できたからといって、だからどうしたって感じだけど。
そーいうのはマクロでどうにでもなるじゃん
Common Lisp のファイルをコンパイルするシェルスクリプトって みんな作ってる?
>>365 scheme の思想を優先、ということですか?
立派な lisper なら不便に思わないのかしら。
>>367 出来ても差し支え無いなら出来た方がいいのに、と思ったんです。
(car '()) や (cdr '()) => error ; #f がほすぃ。これも思想かしらん。 精進するのが最良の選択?
>>370 r5rs とかって、最大公約数的な物なんだと思う。
自分で拡張することが前提っていう。
Schemer 全体の思想っていうより、合意がとれなかったんじゃないかな…
>>370 くらいなら、ほんとにすぐ書けるしね。
372 :
デフォルトの名無しさん :02/10/23 09:16
>>366 私的には
(define a 2)
なら(set! a 1)は2を返してほしいなぁ
373 :
デフォルトの名無しさん :02/10/23 21:44
scheme初心者です。初歩的な質問ですいません。 ((a b) (c))のようなリストを、中のかっこを外すプログラムを作りたいんです。 ((a b) (c))→(a b c) ((a b) ((c)))→(a b c) のような。 再帰を使うんだろうなってことしかわからないです…。 もしよければご教授お願いします。
>>373 私も初心者ですが、こんなのでどうですか?
(define (foo l)
(cond ((null? l) l)
((not (pair? l)) (list l))
(else (append (foo (car l)) (foo (cdr l))))))
>>370 >(car '()) や (cdr '()) => error ; #f がほすぃ。これも思想かしらん。
lisp や scheme は知らないけど、'(#f) や '(|#f) を考えるとあまり便利とは
思えないような。。。
>>374 ありがとうございます!!
実は自分はマニュアルをもっていなくて、いくつかわからないのがあるのですが…。
appendというのは二つのリストをくっつけるものですよね。
ここの(list l)っていうのはどういうものなんですか?
ほんと初心者ですいません…。
あ、 (list l)=(cons l ())ってことですか? いろいろいじってたら同じ結果になったんですが。
>>373 >>374 は惜しい。正解書くと、
(define (flatten l)
(if (pair? l)
(if(pair?(car l))
(append (flatten (car l)) (flatten (cdr l)))
(cons (car l) (flatten (cdr l))))
l))
>376
listは引数リストをリストにして返す関数(list 'a 'b "c") => (a b "c")
>377 list そのまんまリストを作る関数です (list 'a) => (a) (list 'a 'b 'c) => (a b c) (list 'a '(b) 'c) => (a (b) c) 上の例では (list l) = (cons l '()) です
>>378 Oh! 正解どうもサンクスです。精進します
あれ? Lisp に flatten って関数はないのか
382 :
デフォルトの名無しさん :02/10/24 15:23
(define (flatten a) (if (list? a) (apply append (map flatten a)) (list a))
RPL って知ってます? 後置記法な Lisp なのだとか。カッコが無いと嬉しいけど。
んー 俺は括弧が無いと・・・
萌えない。
誰か教えて。 (fucn1 ..) (func2 ..) .. と (progn (func1 ..) (func2 ..) .. ) では最後の戻り値以外何が違うの?
389 :
デフォルトの名無しさん :02/10/25 10:49
質問させてください。 GaucheでSchemeの勉強をはじめたのですが、#<undef>なんてのが 付いてきます。これを消す方法はあるでしょうか? Guileでは付いてこなかったんですが、なにか意味があるんでしょ うか!? gosh> (display "TEST") TEST#<undef> formatを使えばでてこないですね。
TESTはdisplayによる出力で、 #<undef>は(display "TEST")を評価した結果じゃない? 消し方はわかんないけど。
M記法はもう死にましたか?
392 :
デフォルトの名無しさん :02/10/25 23:56
>>390 そうか、displayの出力は副作用であって、結果が#<undef>だと。。
正規表現で削るくらいしか知恵がないです。なにか良い方法があれば、
お願いします。
>>389 ,
>>392 つーか何か勘違いしてませんか?
結果が画面にでるのはインタラクティブモードだからでしょ。
(begin(display) #t)
とすればdisplayの結果は見えなくなって、#tが返りますよ。
[呼ばれて;[飛び出て;[じゃじゃじゃ;[じゃーん;nil]]]]
つーかM記法て何? パーサあるの?
>>M ObjC?
↑だから何?
McCarthyがLisp1.5プログラマーズマニュアルとかで 使ってた「読みやすい」Lispプログラムの表記法。 M式は「Meta Expression」のことだったと思う。 M式が読めるLisp処理系もあったよ。Apple Lispとか。
400 :
デフォルトの名無しさん :02/10/26 15:35
読みやすいの?
>>400 そりゃ人によると思うが…S式よりよみやすいと俺は思う。
ack[x;y] =
zerop[x] -> +[y;1];
zerop[y] -> ack[-[x;1];1];
t -> ack[-[x;1];
ack[x;-[y;1]]];
こんな感じだろ。
なんかMLみたいなコードだな。
403 :
デフォルトの名無しさん :02/10/26 15:54
>>401 それ終端はどう定義されてるの?
関数[引数] = 条件 -> 値 ; 条件 -> 値 ; 条件 -> 値 ; ...?
>>403 あ、忘れてた。最後はピリオドだ。確か。
405 :
デフォルトの名無しさん :02/10/26 16:28
括弧の位置が違うだけじゃないのね。 なんか制限きつそう。
「慣れ」ってのがあるから、それを良いと感じることは、もう出来なさそう。 括弧マンセーLISP の統一感に憑かれた者は特に。
いや、括弧のネストが少ないにこしたことありませんが。
LISP サイコー!!
lispのどこがサイコーなんだい? lisperなんて、舌足らずでものをしゃべってるガキみたいだね。
今更ながら『リスト遊び』を買ってみた。 んー、名著だね。
>>411 あれの次となるとどういう内容になるんだろう。
SICPみたいなの?Emacs LispのBufferで遊んでみるとか?
スキーム手習いを読んでみたい。
原書でどうぞ。The Little Schemer.
schemeの読み方ってスケメで良い?
>416 ネタだよね? マジレスすると、スキームだよな。
ネタニマジレスカコイイ
スチェメ
420 :
デフォルトの名無しさん :02/10/28 11:30
>>393 こんな関数をみなさん使ってるんですか?
displayの返り値なんて気にしない。
すみません、KABAです。
&rest と &body って何か違うの?
名前が違います
defmacroの時は&bodyの方が感じが出る。 &bodyで定義しとくと、プリティプリンタや賢いエディタが 字下げをかっこ良くしてくれるかも。
叛届灼攴矯臆
432 :
デフォルトの名無しさん :02/10/31 18:52
SCMって、なんであんなに速いの?インタプリタのくせに。
>>433 今、ソースコード読んでます。
なんかわかったらまたカキコします。
Scheme 処理系では SCM が最速なの?
>>435 いや、SCMは特に速いほうじゃない。バイトコード処理系に限っても
vschemeやChezScheme Liteの方が段違いに速い。
>>432 他の言語のインタプリタと比べてるのか?
>>436 niftyにあった比較的軽量な実装の(SECDRなど)と比較してます。
そんなに厳密じゃないけど。
petite-chezはread-eval時にネイティブに変換してるからあんなに速いらしいですね。
それとvschemeって、どこのvschemeですか?(この名前の処理系は沢山あるんで)
Petite Chezはネイティブコードじゃない。インタプリタ。 有料のChez Schemeがネイティブコード。Petiteよりさらに速い。
440 :
デフォルトの名無しさん :02/11/01 15:59
>>392 Common Lisp なんかでは
(progn (princ "hog3") (values))
とやると式が値を返さなくなるから
hoge
"hoge"
なんてことにはならないよ。Schemeで
(begin (print "hoge") (valuse))
とやるとどうなるんだろう。
あ、タイーポしちゃった。 "hog3" -> "hoge"
>>442 それは知ってるんですけどね。
本も欲しいんですよ。電車の中とかでも読めるし。
>>440 e と 3 をタイーポするとは T-Coder ?
ちなみに gauche では、
gosh> (begin (display "hoge") (values))
hogegosh>
てな感じです。
>>443 ぼくは会社のプリンタで4ページ/枚で印刷して、
電車の中で読んでる。字がちっちゃくて読みにくいけど。
まだ4章の Utility Function のところで、あんまり
面白くないけど、これから面白くなるのかな?(わくわく)
446 :
デフォルトの名無しさん :02/11/01 18:37
setf ってマクロだよね。xyzzy の lisp/setf.l を開いてみたんだけど 思いのほか色々定義されてて、何やってるのかわかんなかった。 (setq l (cons 1 (cons 2 (cons 3 nil)))) => (1 2 3) (macroexpand '(setf (car l) 2)) => (progn (rplaca l 2) 2) 一般化変数ってなに? 単にフォームの頭で呼び出している関数をみて、マクロ展開する式を選んでいるだけ?
>>446 一般化変数って何処の言葉ですか?
文脈から想像するとおそらくCommonLISPで自然に扱える
値の格納先のことだとは思うけど。
マクロは基本的に静的変換しかできないんで、
setfは代入する対象毎に適当な構文に変換するだけ。
制限とかは自分でマクロ書いてみればわかる。
define-setf-methodは不必要に複雑だよね。defsetfだけでよかったのに。
449 :
デフォルトの名無しさん :02/11/01 23:48
>>439 Petiteはインタプリタだけど動的にネイティブコードに変換してるよ。
つーかそうでもないとあの驚異的な速さは説明できない。
>>449 Cadenceのページにインタプリタだとちゃんと書いてあるだろーが。
native codeじゃなくてthreaded codeだよ。
?ナニソレ>threaded code
threaded codeってのは、 インタプリタの命令実行ルーチンの入り口番地を 中間語の代わりに書き並べるテクニック。 命令実行ルーチンの最後で、次の命令実行ルーチンに 間接ジャンプする。
453 :
デフォルトの名無しさん :02/11/02 00:03
>>450 よくわかんないけど、threaded code=ネイティブコードじゃないの?
言い方違うって怒ってるの?
455 :
デフォルトの名無しさん :02/11/02 00:05
ぐぐれ
(defun (setf cadr) (cons v) ...)とかは邪悪だと思う。 なんであんなの入れたかなー
457 :
デフォルトの名無しさん :02/11/02 00:06
>>452 >中間語の代わりに書き並べるテクニック。
それって内部的にバイトコードに変換してるって事とは違うの?
>>457 違う。バイトコードなんてものはどこにも出てこない。
>>457 ひょっとしてバイトコードとネイティブコードの区別もついてないのか(藁
460 :
デフォルトの名無しさん :02/11/02 00:11
>>458 変換してるタイミングって、インタプリタでの
read->evalのどこかの段階だよね?
単に書き並べただけじゃあんだけ速度出すの不可能だと思うけど。
>>459 中間語をバイトコードって解釈してるんですが、間違ってる?
>>460 >単に書き並べただけじゃあんだけ速度出すの不可能だと思うけど。
書き並べたってのは言葉のあやだが、機械語コード(=ネイティブコード)や
バイトコードでなく、「番地ワード」が並んでるんだよ・・・少しは調べれ。
>中間語をバイトコードって解釈してるんですが、間違ってる?
threaded codeは普通バイトには収まらんな。
中間語=バイトコードってのは間違いだよ。Javaとか(昔の)Smalltalkの
中間語はバイトコードと呼ばれてるが、P(擬似)コードとかI(中間)コード
とか呼んでる処理系もある。
>>461 smalltalkのバイトコードだってバイトには収まりませんよ・・・
まあ byte code も token threaded code の亜種ではあるわけですが。
464 :
デフォルトの名無しさん :02/11/02 00:20
>>461 結局、言い方の問題の気がするんですが。
threaded codeを一般化して呼んだら「バイトコードの一種」みたいな
表現になりませんか?
というか、それよりもネイティブでなくて、なんであんな速いのかが
知りたいだけだったんだけど。
結局threaded codeって、バイトコードのプログラムカウンタが無い様な物
って事でいいのかな?
465 :
デフォルトの名無しさん :02/11/02 00:28
466 :
デフォルトの名無しさん :02/11/02 00:29
また処理系の実装の話題か。
>>462 収まるのもあるしバイト単位で切る意味はある。
threaded codeをバイト単位で切る意味があるかね?
>>463 は、おっしゃるとおり。後世から見た分類だが。
threaded codeの初出は1973。
>>464 だから違うって…速いのは確かだYO
468 :
デフォルトの名無しさん :02/11/02 00:34
ACLtrial版を試食中。 AllegroServeが入っているのを見つけてコンパイルしようとしたけど、メモリ不足で途中でエラーになる。 トライアル版のヒープ制限のせい? だめなら CL-HTTP 試してみようかな。
>>465 のリンク先はわかりやすいね。すばらすぃ。
470 :
デフォルトの名無しさん :02/11/02 00:36
>>465 >>467 あー、リンク先の説明でなんとなく意味わかりました。
飛び先の命令の解析とかが省かれるのかな。
昔(1970年代)、DECのミニコン用Fortranコンパイラは threaded code を出力していた。キャッシュが小さいので threaded codeの方がヒット率が高く、native codeより速くなったそうだ。
473 :
デフォルトの名無しさん :02/11/02 18:49
values使い方わからん
使わんでええ。
>>473 values は、与えられた引数をかえす多値関数で、
(values 'x 'y 'z)を評価すると、"X" "Y" "Z"の3つの値が戻る。
で、主な使い方は戻ってきた値を multiple-value-bind という関数でうけとって評価する。
(multiple-value-bind (変数リスト) 多値関数 実行部)ってな感じ。
適当な例はこんな感じ、
(multiple-value-bind (x y z) (values 1 3 5) (+ x y z))
変な説明だけで、スマソ。
476 :
デフォルトの名無しさん :02/11/02 19:14
Schemeだとvaluesは使いにくいね。 多値を受け取れるのはcall-with-valuesを使ったときのみだから。
ACL使ってるんだけど、やっぱりいいね。 Emacsから使ってると、まさに最強。 C++とかJavaとか使っている奴の気が知れんって感じ?
>>477 具体的にどんな風に使ってるの?
他の処理系とはそんなに違うもん?
有償ソフトの無料版って何か気持悪くて好きじゃないんだけど。
いや、無料版じゃないけど。 他の処理系と違うところか。 まずは、コンパイルしないでテストができる。 これはACLの威力というよりCommon Lispの威力だけど、 書いたら即テストできるということで、たいへん良いです。 最近はRuby+RubyUnitで開発してたんだけど、UnitTestを 繰り返し実行するのって、半ばコンパイルしているような ものなので、ACLのスピード感からすれば眠っているよう なものだって感じです。UnitTestが「楽しい」ので、つい つい時間を無駄に使っているってこともあるんですが。 Lisp/Schemeでボトムアップで開発するときには、テスト を最小単位できちんと行うせいか、UnitTestのようなテス ティングフレームワークを必要に感じません。 あと、処理系が軽いのが魅力です。コンパイルしなくても 十分に速いし、コンパイル自体も非常に早い。僕のマシン ではJDK+ANTは遅すぎます(いわんやForteをや)。 Emacsから使うと関数名を補完してくれるし、オンライン ヘルプもEmacsの中で見れる。関数の定義にジャンプする こともできる。まあ、まだ大規模な開発に使っていないの で断言すべきじゃないだろうけど、かなりいい感じなのは たしか。
480 :
デフォルトの名無しさん :02/11/02 21:22
(define x (vector 1 2 3 4)) (define y (vector 1 2 3 4)) (vector-set! x 0 y) (vector-set! y 0 x) (vector-set! x 1 x) (vector-set! y 1 y) (display x) #(#(#(#(#(#(#(#(#(#(#(#(#(#(#(#(#(#(#(#(#(... こういうやばいコードの対策張ってある処理系てある? petiteはメモリ食いつぶしてあぼーんです。(つーかOSが悪いのかも)
481 :
デフォルトの名無しさん :02/11/02 21:24
ちなみにpetiteはdisplay使わずに単にxの評価すると、 > x Warning in pretty-print: cycle detected; proceeding with (print-graph #t). #0=#4(#4(#0# 2 3 4) 2 3 4) こうなるけどね。
>>477 う、金持ちやね。
会社に買わせるってのはありかな。
LispはPerlやPythonより優れているのですか?
「優れている」を定義せよ。
>>483 少なくともPerlやPythonにできないことをLispはできるな。
またマクロの自慢かよ。
489 :
デフォルトの名無しさん :02/11/03 00:07
Lisp (できれば Scheme)でマクロの上手な使い方説明してる (チュートリアルっぽい)サイトってあります?
Lispやりたいんだけど、VCをいくらやっても終わらないからやれない・・
>>491 Virtual C ですからw 電源を抜くまで終わりません。
(send.frame.show.#t) これってどういう意味ですか? Schemeは調べるにも調べられなくてこまります。。。
495 :
デフォルトの名無しさん :02/11/03 21:05
frame に show させる。 引数は #t。
498 :
デフォルトの名無しさん :02/11/04 03:19
.で繋げて書く処理系ってあるの?
PerlやPythonに「新しい文法」を導入しようと思ったら、言語処理系自体に 手を入れるか、プリプロセッサを利用するしかない。前者は非常に困難であ る上に言語処理系のバージョンアップに追随するときの問題も無視できない。 後者はインタプリタの便利さを損なう上に、機能の直行性を阻害する危険が ある。その点、Scheme/Lispのマクロなら、自然に新しい文法を導入できる。 たとえばPerlにRuby風のイテレータを導入するとして、どうやればいい? # もっともPythonにはDylan風のマクロを導入するプランがあるようだが。
501 :
デフォルトの名無しさん :02/11/04 14:46
Schemeはスクリプト言語ですか?
>>501 そんなことない。コンパイルする処理系も多いよ。最近はインタプリタの
方が相対的に多いけど、昔は効率の良いコンパイラの議論がずいぶん
Schemeを使ってやられたものだ。
そうですか、スクリプティングには使えないのですか…残念です。
>>503 あ、誤解させちゃったか。
Scheme言語そのものはスクリプティングできるかどうかとは関係ない。
Schemeという言語仕様に対してその実装がいくつもあって、中には
コンパイルして実行ファイル作ってってのもあるし、スクリプティング
に使えるものもある。
手軽にスクリプティングに使えるのはscm, guile, gaucheあたりかな。
そうですか、スクリプティングに使えるのですか…残念です。
508 :
不明なデバイスさん :02/11/04 18:37
次々のプログラムを評価するが、戻り値はいらない場合、どのようにしてますか? (begin <式> <式> <式> (define tmp <式>)) とかいうめんどいことやってるのですが・・・。
「次々の」→「次々と」
(define tmp <式>) も戻り値はあるのでは いらないなら単に無視すればいいのでは
>>508 結果が出力されるのはインタラクティブ(対話)モードだからでしょ。
それを切るか、ファイルから読み込ませれば?
(load "hoge.scm")
512 :
デフォルトの名無しさん :02/11/04 20:01
call-with-output-fileとかって、 call/ccとかdynamic-windの影響受けるとか仕様決まってますか? throwしたときとかで、ファイルを閉じて欲しい時(エラーとかで以降復帰 しないのが確定してるとき)と、ファイルを開いておいて欲しい時(後で 処理再開したいとか)があるんで。 この辺自分で面倒みなきゃならないのかな。
514 :
デフォルトの名無しさん :02/11/04 20:37
>>507 sendとframeはわかったけど、showはquoteされてないって事は、
何か入ってるんだよね。これシンボルじゃないの?
sendがマクロだとすれば納得いくけど・・・。
send -> objectにメッセージを送る
frame -> object
show -> メソッド?
#t -> 引数
というか、これ使ってるのDrSchemeみたいね。(ドット表記じゃないけど) sendの実装読んでみます。
これだね。やっぱ(object 'message)形式に直してた。 (define-macro send (lambda (object message . args) `((,object ',message) ,@args)))
>>512 R5RSの6.6.1に書いてあるよ。原則として、call-with-output-fileとかに
渡したprocedureから外側のcontinuationへ飛び出したとしても、
ポートは自動的には閉じられない、ただしポートが二度と利用されないと
証明できるなら閉じても良い。
Gaucheのマニュアルにも言及があった。(6.18.3ファイルポート)
Gaucheではprocedureがエラーを投げたら閉じられるそうだ。
518 :
デフォルトの名無しさん :02/11/04 21:07
Lispの勉強をしたんですけど、 処理系というかIDEってないんですか? OSはWindowsです。
>>518 Lisp Builder9.0がBorlandから発売されている。
そんなのがあれば即買いだな
521 :
デフォルトの名無しさん :02/11/04 21:45
>>517 どうもです。
やっぱトップレベルとかに落ちるときに状況によって
切り分けが必要ってことですね。色々試してみます。
signalとかで停止した時に後で再開できたら面白いかも。
9.0 まで出てるのか(藁
524 :
デフォルトの名無しさん :02/11/04 22:12
やっぱりemacsでLispと VC++でC++とかEclipseでJAVAを比較してしまうと あきらかに生産性が・・・・ 簡単なやつならいいんだけどね。
へえ? VC++でC++にせよ、EclipseでJavaにせよ、 「コンパイルしないとテストできない」 って問題があるじゃん? Lispなら、書いたその場でテストできるじゃないですか。 VC++やEclipseのメリットって変数名やメソッド名を補完できる ことだけど、それはEmacsでもできるし。プロジェクト管理や バージョン管理も特にEmacsが劣っているとは思わないが。 何を開発する場合での比較ですか?
>>524 そんなに違う?
Abbrev とか Gtags とか Speedbar とか結構便利だと思うんだけど。
あ、ここに書くなら etags ダターヨ。
VC++やEclipseってプロファイラはあるの?
>>528 VC++のは、昔使ったことあるけど。
PREP、PROFILE、PLIST
530 :
デフォルトの名無しさん :02/11/05 06:33
リストの長さを判定したいんですが、たとえば「長さ3以上のリスト」 という限定的な判定をしたい時に使える一般的な関数ってありませんか? (>= (length longlist) 3) これだと効率悪いんで・・。
531 :
デフォルトの名無しさん :02/11/05 07:22
(define (over? l n) (cond ((zero? n) #t) ((null? n) #f) (else (over? (cdr l) (- n 1)))))
>>530 (nthcdr 2 longlist)
>>530 (and list (cdr list) (cddr list))
534 :
デフォルトの名無しさん :02/11/05 13:22
>>532 ,
>>533 こういう時は nil == boolean false は便利だなあ。
Schemeの () ≠ #f というストイックさも好きなんだが。
535 :
名無しさん@Meadow :02/11/05 13:59
>>442 漏れも on Lisp PDF版を印刷して読んでるクチ。
現在 "6. Functions as Representation" に入ったところ。
他にも読んでる人がいるというのは励みになるよ。
で、ちょっと疑問に思ったのが lrec。
fold/reduce との違いというか、あえて関数返すのはなぜ?
536 :
デフォルトの名無しさん :02/11/05 17:21
>>518 Windows版 Allegro Common LispはIDE。
フォームエディタとかプロパティインスペクタとかプロジェクトマネージャーとか
他にありそうなものは大抵ついてる。
>>535 筆者の趣味。ってか、あの本の主題は、「Lisp のパワーの源は、
動的にプログラムを構築して、それを実行することにある。」って
ことだから、あそこは関数を返すのが自然な流れなんだと思う。
今朝 6. を読み終わったけど、node を closure で表すってのは
すごく違和感がある。ずっと OO やってるせいか、node を class
にする方がはるかに自然に思えるよ。。。まだまだ修行が足りない?
ありがとうございます。 nthcdrがシンプルなので使ってみます。
Schemeで作ったソフトウェアにネットワーク機能をつけるには 一体どうしたらいいのでしょうか。 具体的にはパケットのやり取りがしたいのですが、 どうんな関数があるのか検討もつきません。 お勧めのサイトとかありませんか?もちろん英語でもかまいませんので。。
処理系くらい書け。
541 :
デフォルトの名無しさん :02/11/07 01:16
>>539 処理系毎に独自に実装されてるはず。
つーか標準的なソケットライブラリ欲しい。
SRFIでもなんでもいいから標準化してほしいな。
いまどきネットワーククライアント書く共通的な手段が無いのは辛い。
処理系によって違うんすか。
そんなことも知らないのか。
gaucheがおすすめ。 SRFIも主要なところはほとんど実装している。
545 :
デフォルトの名無しさん :02/11/07 15:01
Lisp のシンボルってプロパティをもてますが、それを構造体やハッシュなんかの代わりに積極的に使っていくというのは 1) 推奨 2) 非推奨 3) どちらとも言えない どれ?
546 :
デフォルトの名無しさん :02/11/07 19:27
どれかは、私にゃ分からんが、 ずーっと以前、ハッシュの無い処理系で書かれたとてつもなく遅い アプリケーションをその技を使って書き換えたら、非常に快適になった、 (当り前か)という経験をした事がある。
547 :
デフォルトの名無しさん :02/11/07 19:34
プロパティを持てるってのは何?
あたしは plist のことだとおもったんだけど違いましたっけ。
>>547 シンボル毎にユニークな所を利用して属性が持てる機構って、知らない?
(get sym propname) ; 参照
(put sym propname value) ; 設定
550 :
デフォルトの名無しさん :02/11/07 23:56
>>549 知らんなあ。Common Lispか?
>>550 CommonLispつーか、それ以前からあるけど。
昔、構造体もハッシュもないころはplist使うしかなかったけどね。 symbol-name, symbol-function, symbol-value全部plistに入ってた。 今は使う意味あんまりないでしょう。Schemeみたいにplistなくしちゃった Lisp方言もあるくらい。
554 :
デフォルトの名無しさん :02/11/09 04:49
ベンチマークやってみた。 (tak 27 18 9)と(ack-list (make-list 3) (make-list 8)) tak ack-list qscheme 3.28 1.32 scm 11.85 3.02 petite 5.72 1.03 gosh 10.99 9.42 guile 59.93 (実行できず)
555 :
デフォルトの名無しさん :02/11/09 06:57
Windows上でちょいとSchemeのプログラミングすることになったんですが、 初心者が触るならどのソフト使えばよかですか? どうかご教授ください。
Dr.Scheme かな? 知らんけど
Chez Scheme.
まず過去ログを読む。
頭悪そうなやつに限って「ご教授」という言葉を使うような気がするのですが なぜですか?どうかご教授ください。
>>554 ほー、qschemeって速いね。
petiteより速いとは。
qschemeはwin版がない
Win版なんていらねー,と言ってみたい今日この頃
563 :
デフォルトの名無しさん :02/11/09 12:41
cygwinでコンパイルできない?
いる! Windows only ならいらんけど。
cygwinにしたら速さを実感できない
566 :
名無しさん@Emacs :02/11/09 13:30
Guileおそいねえ..
>>554 つい GNU謹製だからって使い続けてたんだけど。
まあ、簡単な scriptingにしかつかってないからいいっちゃいいし、
directory 読む関数とか処理系依存のものばりばりつかってるから
いまさらうつれなかったり。
まえにもあったけどそこらへんの OS依存の dirtyな部分の標準ほしいな。
568 :
名無しさん@Emacs :02/11/09 20:48
fileの属性とかならOS依存だけど、 directory読むくらいならOS依存じゃないよねぇ。
このようにして、Common Lisp のような 肥大化したシステムが作られてゆく。 べんりだけど。
SRFIにファイルI/Oの拡張が入ってないのが不思議だね。
では標準関数も諦めます
(gc)
575 :
デフォルトの名無しさん :02/11/11 01:42
>570 CommonLISPもソケットとかの仕様無いよね?
CommonLISPの仕様ができたのは80年代だから…
578 :
デフォルトの名無しさん :02/11/11 21:24
たしかに要るね。 #define MAKE_PAIR(x) ((SCM)(((x)<<2)|2)) だな。
>>579 のURLに書いてあることは(大体は良いんだが)素直に
うなづけない事もあるな。
Use complex numbers to represent points in a plane.
とか、SETFでなくてSETQを使えとか。
〜 Programming Style なんてみんなそんなもんでそ 綺麗事だけでやっていけるんなら最初からそんな仕様を作らないし
SETQ力がないな。
CDR ないこと言わないで下さい。
CONDのは自信あるよ。
君らATOMがおかしいんじゃないか。
Tっとりばやく他人のをまNIL
>>579 ありがとう。別のデータ構造を使うことにするよ。
がっこーのSchemeの課題で 「リスト構造の中にアトムがいくつあるか数える関数を作れ」って問題が出たんですが、 どう解釈すればいいんだろう… 例えば(1 (2 3) 4)は1,2,3,4の4つに見えるんですが、 ドット対を用いて書き直すと (1 . ((2 . (3 . ())) . (4 . ()))) になるから、1,2,3,(),4,()で6つになるようにも思えます。
() は atom じゃないんじゃない?
590 :
デフォルトの名無しさん :02/11/12 22:19
Petite Chez Scheme Version 6.0a Copyright (c) 1998 Cadence Research Systems > (atom? ()) #t
>>590 atom? って Scheme の標準手続きでしたっけ?
あと、やるなら
(atom? '())
でわ?
特に言及されていない限り、リストと言えば一直線だと 思うのだが。 つまり問題は「与えられたリストの要素の中でアトムであるものの 数を報告せよ」と言い換えることができて、 (1 (2 3) 4) の場合それは2だろうと思うわけだが。
>>つまり問題は「与えられたリストの要素の中でアトムであるものの >>数を報告せよ」と言い換えることができて、 そうなの? わざわざリスト構造の「中に」っていってるんだから全部数えるんじゃないかなぁ?
(define (count a) (if (list? a) (apply + 1 (map count a)) 1)) こうかな。
> (count '(1 (2 3) 4)) 6 > (count '(1 (2 . 3) 4)) 4 うーん......
Is it true that this is an atom? () No, because () is just a list.
>>591 Scheme には atom? はない。
それと () も '() もいっしょ。
598 :
デフォルトの名無しさん :02/11/12 22:48
'()と()に区別はあるのかな? '()は(quote ())のシンタックスシュガーだが、 ()を評価しても()を返すので、結局同じ。
>>597 >>それと () も '() もいっしょ。
そうでした。すいません......(汗
(define (count a) (if (pair? a) (+ (count (car a)) (count (cdr a))) 1))
Schemeでは()と'()は違う。 ()は正しい式ではない。
R^5RSの4.1.3 Procedure Callsより: Note: In many dialects of Lisp, the empty combination, (), is a legitimate expression. In Scheme, combinations must have at least one subexpression, so () is not a syntactically valid expression.
603 :
デフォルトの名無しさん :02/11/12 23:02
R^5RSを読み直してみたが、What is ATOM?の回答を得るには至らなかった。 Lisp的にはAtomはconsではないすべてのオブジェクトである。そしてnullは consではない。 ...思うに、schemeでatom?が標準関数でないのは、それが本質的ではないから ではないか? (pair? x) がtであれば、それはアトムではない。だから(atom? x)は(not (pair? x))に 過ぎないわけで、あえて仕様に含める理由はないのではないか。
なんで not pair なら atom なの? >(list? '()) #t
スマソ
()はlistでありatomだ。
608 :
デフォルトの名無しさん :02/11/12 23:13
nil( = '() )はアトムっすよ
>>608 nil = ()
からして間違いです(Scheme では)
つまり課題は再帰関数かけってことだな。 (define (count-atom s) (if (pair? s) (+ (count-atom (car s))(count-atom (cdr s))) 1)) >(count-atom '(1 2 (3 4))) =>6
R^5RSでatomという言葉は7.9のプログラム例の変数名として 出てくるだけだ。そういう概念は使わないことにしたらしい。 ()はlistだがpairではない、ただ1つの要素しかもたない特別な 型の値。 nilについては「空リストでも偽(#f)でもない、ただのシンボル」 となっている。
なるほど
つまり
>>588 の解答は
(define (count-atom x) 0)
が正解なんですね?
>>612 なんでそうなるの?リストの中のアトムを数えるんでしょ。
>>613 いえ、Scheme でアトムという概念を持ち出した出題者のミスってことで.....
もち、ネタです。スマソ
NULLホド!
(define (atom? x) (not (pair? x)))
(define (atom? x) (not (list? x))) 説もある。
>>617 Common Lispと同じように定義するならそうなるな。
俺も617の方だよ。
(define atom? (lambda (x) (and (not (pair? x)) (not (null? x)))))
622 が正解だと思う
>>622 えー、それ変だよ。
今までのどのLispの定義とも違うと思われ。
Lisp1.5だと記号アトム(今で言うsymbol)、数値、consセルの3つしか データ型がなかったからな。 基本5関数がcons, car, cdr, eq, atom。 (atom '())の値はTだった。
結局(and (atom? x) (null? x))が成り立つかどうかなのか?
Scheme では () は空リストである。 それ以外の何でもない。 とりあえず Scheme 以外の Lisp 方言の常識を持ち出すのはやめれ。
>>626 Lisp1.5だとNUMBERPも基本に入るんじゃないか?
あと、RPLACA, RPLACDがあれば、インタプリタ全体がLisp自身で書ける。
Pure Lispだと数値もないよね。だから5関数でOK。
盛り上がってきましたぁ (gc)
とりあえず、Revised Report 〜 Revised^4 Reportまでには atomという言葉は出てこないみたい。 RevisedとRevised Revisedはサーチ出来ないので「絶対」とは 言い切れんが。
633 :
デフォルトの名無しさん :02/11/13 00:08
>(define (count-atom s) >(if (pair? s) (+ (count-atom (car s))(count-atom (cdr s))) 1)) これを、再帰(末尾呼び出しは可)も副作用も破壊も無いものに 書き換えるとしたらどうなりますか?
末尾再帰と呼べるかどうか・・・ (define (count-atom s) (let loop ((s s) (f (lambda (x) x))) (if (pair? s) (loop (car s) (lambda (x) (+ (f x) (count-atom (cdr s))))) (f 1))))
答えは正答者がいなかった場合に、1時間ぐらい後に出します。
>>634 >(lambda (x) (+ (f x) (count-atom (cdr s)))))
この部分が末尾再帰になってないです。
(define (count-atom list) (define (count list n cont) (cond ((null? list) (cont n)) ((not (pair? list)) (cont (+ n 1))) (else (count (car list) n (lambda (result) (count (cdr list) result cont)))))) (call/cc (lambda (c) (count list 0 c))))
こうか?もうわからん。末尾でなくてもいいやん。 (define (count-atom s) (let loop ((s s) (f (lambda (x) x)) (n 1)) (if (pair? s) (loop (car s) (lambda (x) (loop (cdr s) f x)) (+ n 1)) (f n))))
次の問題です。 2つの木構造の葉(空リストを除く)に、eqv?なものが同じ順序で 現れるとき#tを返し、そうでないとき#fを返す関数 (compare-leaves tree1 tree2)を定義しなさい。
>>636 正解です。なんかベテランっぽいコードですね。
(ちなみにcall/ccが無くても解けます)
(define (compare-leaves tree1 tree2) (or (and (pair? tree1) (pair? tree2) (compare-leaves (car tree1) (car tree2)) (compare-leaves (cdr tree1) (cdr tree2))) (eqv? tree1 tree2)))
>>639 cal/ccを使わずidentityを渡しても解けるが、pushy continuation
を使わず、jumpy continuationだけに統一したほうがきれいだと思った。
>>640 それはただのequal?ですね。
ではなくて、たとえば、
(compare-leaves '(a (b) c) '(((a) b) c)) => #t
(compare-leaves '(a b . c) '((a (b)) c)) => #t
となるものを作ってほしいのです。
(define (flat a) (cond ((list? a) (apply append (map flat a))) ((pair? a) (append (flat (list (car a) (cdr a))))) (else (list a)))) とかかけてequal?したらダメ?
>>643 はい。正解です。
では、次に、末尾再帰だけ使って書いてください。
(ちょっと眠いので早めですが) こちらで用意していた答えはこれです。 (define (count-atom s) (let loop ((s s) (stack '()) (count 0)) (if (pair? s) (loop (cdr s) (cons (car s) stack) count) (if (pair? stack) (loop (car stack) (cdr stack) (+ count 1)) (+ count 1)))))
646 :
デフォルトの名無しさん :02/11/13 00:45
(define (count-atom l) (define (c l r) (cond ((null? l) r) ((not (pair? l)) (+ 1 r)) ((pair? (car l)) (c (append (car l) (cdr l)) r)) (#t (c (cdr l) (+ 1 r))))) (c l 0))
(c (append (car l) (cdr l)) r)) ってどうなんだろ。
>>647 '(1 (2 3 . 4) 5)
とか子リストがドットペアの場合に駄目だと思う。
>>644 (define (foo x) ... (cons x (lambda () ... (foo ...))))
は末尾再帰とみなすのか?
>>649 クロージャ内の終端式なら末尾再帰とみなせますよ。
ちなみに633 != 638
普通は flat でなく flatten だろう
>>644 (define (compare-leaves tree1 tree2)
(let loop ((a tree1) (stacka '())
(b tree2) (stackb '()))
(cond ((pair? a) (loop (car a) (cons (cdr a) stacka) b stackb))
((pair? b) (loop a stacka (car b) (cons (cdr b) stackb)))
((and (null? a) (pair? stacka))
(loop (car stacka) (cdr stacka) b stackb))
((and (null? b) (pair? stackb))
(loop a stacka (car stackb) (cdr stackb)))
((and (null? a) (null? b)) #t)
((eqv? a b) (loop '() stacka '() stackb))
(else #f))))
うむ、面白いな。
>>654 なるほど…スタックを使うんですね。
ちなみに私が用意してた解答はこんなのです。consは(陽には)使いません。
define (compare-leaves tree1 tree2)
(define (next-leaf tree next yield)
(cond ((null? tree) (next yield))
((not (pair? tree))
(yield tree next))
(else (next-leaf (car tree)
(lambda (y) (next-leaf (cdr tree) next y))
yield))))
(define end-of-list '(unique-pair))
(define (compare process1 process2 exit)
(process1
(lambda (leaf1 cont1)
(process2
(lambda (leaf2 cont2)
(cond ((eq? leaf1 end-of-list) (exit (eq? leaf2 end-of-list)))
((eq? leaf2 end-of-list) (exit #f))
((eqv? leaf1 leaf2) (compare cont1 cont2 exit))
(else (exit #f))))))))
(call/cc (lambda (exit)
(let ((no-more (lambda (yield) (yield end-of-list 'never-call-me))))
(compare (lambda (co) (next-leaf tree1 no-more co))
(lambda (co) (next-leaf tree2 no-more co))
exit)))))
>>656 他人のやつは読めないねえ。
後半あたりさっぱりわからん。
あとでゆっくり読んでみます。
>>657 コルーチンを使ってます。
他にも、lazyなリストを使うやり方もあると思います。
659 :
デフォルトの名無しさん :02/11/13 01:52
副作用が無いとメンテがしやすい
660 :
デフォルトの名無しさん :02/11/13 09:53
define-syntaxの使い方が良く分りません。 mapcarと同じ記法でdoに展開するマクロを作りたいのですが、 以下ではダメなようです。正しくはどう書くのでしょう? (define-syntax amapcar (syntax-rules () ((amapcar fun list1 list2 ...) (do ((v1 list1 (cdr v1)) (v2 list2 (cdr v2)) ... (result '() (cons (fun v1 v2 ...) result))) ((some? null? `(,list1 ,list2 ...)) (reverse result))))))
たぶん、 (fun v1 v2 ...) のとこで、そんな省略は解釈できないってことだと思う。 pattern のとこには、 v2 なんて名前の後に省略記号はこないから。 名前として使えるのを別に渡すようにするか、自力で生成するかしないといけなそう。 とりあえず、後者で書いてみたけど… list の長さが違うときの挙動は、これでいいのかな? (letrec-syntax ((amapcar (syntax-rules () ((_ "generate" ((sym val) ...) () fun) (do ((sym val (if (null? sym) sym (cdr sym))) ... (result '() (cons (fun (if (null? sym) sym (car sym)) ...) result))) ((and (null? sym) ...) (reverse result)))) ((_ "generate" (xs ...) (y . ys) fun) (amapcar "generate" (xs ... (sym y)) ys fun)) ((_ fun list ...) (amapcar "generate" () (list ...) fun))))) (amapcar cons '(a b c d) '(1 2 3))) => ((a . 1) (b . 2) (c . 3) (d))
mapとmapcarって違うの?
schemeのmapはmapcar
665 :
デフォルトの名無しさん :02/11/14 11:27
>>662 うーん、難しい…
マクロも同じ言語で書けるのはLispの大きな(最大の?)利点だったのに、
何でSchemeはわざわざ別のマクロ言語を発明しちゃったんだろ。
なんか前にあったな。マクロの問題点とかいうの。 議論についていけなかった・・・。 評価がどうのこうのとかいうのだと思うが。
>>660 昨日、それ印刷して帰りの電車で読んでみたけど、睡魔が襲ってきて
乗り越しそうになったよ。
で、結局 fringe って何をする関数なわけ? iterator のどこが
いけないの?
668 :
デフォルトの名無しさん :02/11/14 17:23
「木の葉を数えあげる」というような単純な問題さえ iteratorでは(friendのようにデータ隠蔽を破る汚らしい手段を使わないと) 記述できない。
>>668 回答さんきゅ。fringe って木の葉のこと?
うーん、iterator が「データ隠蔽を破ってる」とは思わないんだよね。
だって、iterator は、対応するコレクションクラスと対をなすもの
だもん。だから、お互いに実装詳細を知ってるのは当たり前って気が
するんだけど、、、変かな?
逆に、あの論文だと、lazy evaluation な fringe に対しては、
普通の equal や samefringe とは別に、lazy evaluation 版の
lequal や lsamefringe を用意する必要があるわけで、それは
いまいち美しくないと思うんだけど、、、やっぱ修行が足りないかも。
>>669 fringeとは「縁(ふち)」のこと。
「木」「グラフ」その他なんでも(数値的な探索ステップとかでも)、
「順にたどる手続き」が与えられれば、そこから容易に「列」
を得ることが高階関数を用いればできる。しかも、必要に
応じてlazyなストリームとしても、generatorとしても、coroutine
としても得ることができる。「数えあげる手続き」から「列」
への変換の仕方は直観的で一様だ。
しかし、C++などはそうでない。例えば自然言語の構文木が2つ
あったとして、それらの終端記号の並び方が同じか(つまり、同じ
自然言語の文を解析した木か)をエレガントに判定するには、
構文木のクラスに手を加えて、内部を知っているiteratorを付け加え
なければならない。
こうやってはすかーがせいぞうされてゆく。
672 :
デフォルトの名無しさん :02/11/15 00:55
C++でも順にたどればいいんじゃないの?
>>672 2つの木の縁だけ比べる話をしてるんだが、理解しているか?
木の葉を順に返すiteratorを書いてみてくれ。
で、それは木を単にたどるプログラムと似ても似つかないと思うが?
>>673 (define foo (hoge '(1 (2 3) 4)))
ってしたら
(foo)->1, (foo)->2, (foo)->3, (foo)->4, (foo)->()
になるhogeを書けってこと?
C++なんてわからないんだが・・・
>>654 みたいなやつではあかんの?
順にたどってるでしょ。
>>676-677 話の筋を追ってほしいんだが。
C++ではなぜ駄目かを説明しているのに対し
>>672 があって、
じゃあC++で書いてみろ、という話なんだが。
>>665 Haskell とかの pattern match がうらやましかったんじゃないかな…なんて。
あれだと、処理によってはすごくきれいに書けるから。
今までの low-level macro とか、他の関数とかと混在できれば、
もっと楽しそうなんだけどね…
だから、順にたどればいいんじゃないの?
>>680 順にたどるのを途中で止めてメソッドからリターンし、
次に呼ばれたときに再開しなきゃならんのは分ってる?
C++で書いてみて。
(昔SIGPLAN Noticesに「thread使えば書ける」ってのが載ってたが。)
終端文字までたどって、もう一方も終端文字までたどって 等しくなかったら#f返して、等しかったらループにして 最後まで来たら#tってすればいいんじゃないの?
>>682 いったいぜんたい何の話?
C++は分らない人? なのにC++の擁護してるの?
>>673 みたいなもの(iteratorと呼びます)をC++で
どうやって書きますか?という話なんだが。
>>683 iteratorってのは
>>674 みたいなの?
それだったらiterator使わなくても
等しいかどうかの判定はできると言っているのだが。
>>684 等しいかどうかってのはただの一例で、
そういう問題も簡単に書ける部品を、
抽象度高くかけますか? と問うている問題なの。
>>684 itaratorの話をしてるわけだが。
>>683 ところで、iteratorとは逸れるが、2つの形の違う木について
同時にループするってどうやるの?
iteratorでどれくらいエレガントに書けるのよ。
>>689 bool SameFringe(Tree tree1, Tree tree2) {
for (TreeIterator t1(tree1), t2(tree2); t1.hasMore(); t1.next(), t2.next())
if (! t2.hasMore() || t1.current() != t2.current())
return false;
return true;
}
>>690 最後って
return t2.hasMore() ? false : true;
}
の間違いだよね?多分。
>>693 英語読めんよ。
コードをちらっと見た限りではこんなlambdaが多すぎるのは、
等しいかどうか程度の判定には必要ないと思っているんだが。
lispプログラムのエントリポイントって、どうなってるんですか? c++とかjavaのmainにあたるものって何ですか?
age忘れ
一番上の行
ネタでした。
700 :
デフォルトの名無しさん :02/11/15 10:05
結局イテレータの話はなんなの? 外部イテレータより内部イテレータの方が有利ってこと?
702 :
デフォルトの名無しさん :02/11/15 10:24
>>700 samefringeみたいに2つ以上のセットへのイテレーションが絡む
時には、イテレータじゃ書きにくいよってことなんかな。
外部イテレータを使うと、イテレータ内部で自前でスタック管理みたいな
ことが必要。
内部イテレータを使うと、何らかの方法で一方のクロージャから
もう一方のクロージャに制御を移す必要があるんで、コルーチンか
スレッドが必要。逆にコルーチンかスレッドが使えるなら内部イテレータ
最強。みたいな感じ?
703 :
デフォルトの名無しさん :02/11/15 10:39
いまさらだけど、
>>656 でcall/ccを使ってるのはなんで?
exitなくても動くよね?<(lambda(x)x)で試した
>>702 確かにクロージャの数珠繋ぎでなんでも列にできるのは便利だね。
列を保時する一時変数を持たせれば、そのままC++系のイテレータスタイル
にも持っていけるきがするけど。(ただし内部で破壊代入が一箇所必要)
(let ((i1 (make-leaves-iter tree1))(i2 (make-leaves-iter tree2)))
(let loop ((l1 (i1))(l2 (i2)))
(if (eqv? l1 l2)
(if (null? l1) #t (loop (i1) (i2)))
#f)))
それとデータ隠蔽の件だけど、
>>656 のnext-leafは木の辿り方を知ってるって事になるんじゃない?
これって、データ隠蔽とはちがくない?
それとも
>>660 のdefmethodを使った場合に限っての話?
どのみち1つのオブジェクトに対応したC++コレクションイテレータの
nextに相当する物は無いとまずいんだよね?
705 :
デフォルトの名無しさん :02/11/15 13:21
木の複製も似た方法でできる? (define x '(a (b c) d . e)) (define y (copy-tree x)) (eq? x y) =>#f (equal? x y) =>#t
706 :
デフォルトの名無しさん :02/11/15 14:04
コルーチンてなに?
707 :
デフォルトの名無しさん :02/11/15 14:07
内部イテレータ(w いまどきそんな用語使うのはRubyistくらいと思われ(w
外部イテレータに対しての内部イテレータ。 別におかしいとは思わないが。
709 :
デフォルトの名無しさん :02/11/15 14:08
>>704 データ隠蔽は
>>600 論文の主題とは関係ないよね。
The major problem with iterators is that they are non-functional
functions--they depend upon an internal state and side-effects to operate. It is very difficult to prove anything about functions with
state, and therefore such functions inhibit most compiler optimizations. But the most damning criticism of iterators occurs in the context of
multitasking and parallel threads. When using parallel threads, all side-effects must be protected by locks, in order to ensure the
consistency of interpretation of the contents of shared objects with
state. While most iterators in C++ are locally-defined for a particular
loop, and therefore not shared with any parallel process, it is
difficult for a compiler to prove this. As a result, one is either left
with an inefficient program, or a potentially dangerous program,
depending upon whether the compiler inserts locks to be on the safe side, or leaves them out in the name of efficiency.
710 :
デフォルトの名無しさん :02/11/15 14:10
>>708 今「イテレータ」と言ったらRubyistの言う外部イテレータのこと。
>>712 continuation-passing styleで書いていているのに、
陽に渡されたcontinuationにジャンプするのでなく
「その場所に積まれた」continuationにリターンする
のはおかしいだろう。
716 :
デフォルトの名無しさん :02/11/17 05:28
>>705 これであってる?
(define (copy-tree s cps)
(if (pair? s)
(copy-tree (car s)
(lambda (c)
(copy-tree (cdr s)
(lambda (d) (cps (cons c d))))))
(cps s)))
(copy-tree '(a (b c) d . e) identity)
=>(a (b c) d . e)
717 :
デフォルトの名無しさん :02/11/17 05:28
718 :
デフォルトの名無しさん :02/11/17 09:33
(open-input-file "hogehoge.file")で、 ファイルが開けないとエラーが出てとまってしまいますよね。 これを、エラー時には再度やり直す等、引き続き処理を続行させたい場合どうしたらいいのでしょうか?
721 :
デフォルトの名無しさん :02/11/17 11:58
すいません、質問です。 (define (loop-test) (let loop ((x 0)) (or (and (even? x) (begin (display 'even) #t) (loop (1+ x))) (and (odd? x) (begin (display 'odd) #t) (loop (1+ x))) (begin (display "does not reach here") #t)))) このloopは末尾再帰じゃないんですか? メモリを消費しすぎて死んでしまいました。 orの使い方がまずいのかなあ。
722 :
デフォルトの名無しさん :02/11/17 13:46
(and (even? x) (begin (display 'even) #t) (loop (1+ x))) (and (odd? x) (begin (display 'odd) #t) (loop (1+ x))) が#tじゃなかったら(再帰がおわるまでわからない) (begin (display "does not reach here") #t)))) を実行しないといけない。 普通condやね。 (define (loop-test) (let loop ((x 0)) (cond ((even? x) (display 'even) (loop (1+ x))) ((odd? x) (display 'odd) (loop (1+ x))) (else (display "does not reach here") #t))))
723 :
デフォルトの名無しさん :02/11/17 15:37
>>721 それは、(even? x)か(odd? x)のいずれかが真になり、
しかもloopの再帰呼び出しからは帰ってこないので、
(display "does not reach here")が最適化で消えて、
loopの呼び出しが末尾再帰になるという狙いでしょうか?
そういう最適化をしてくれるコンパイラは無いと思います。
loopはandの末尾に置いてあるから、問題は別の個所。 何が起きてるのかは、STACKのDUMPが取れる環境ならすぐわかる。
>>724 そうじゃないと思う。
orの途中にあるから、and自体が末尾にない。
andとorを展開すればわかるか。 (define (loop-test) (let loop ((x 0)) (let ((g1 (if (even? x) (if (begin (display 'even) #t) (loop (1+ x)) #f) #f))) (if g1 g1 (let ((g2 (if (odd? x) (if (begin (display 'odd) #t) (loop (1+ x)) #f) #f))) (if g2 g2 (begin (display "does not reach here") #t)))))))
ええとつまりandがor展開時のletの引数の部分に当たるから 末尾再帰してくれないということですか? なんかorって不便ですね。 結果をそのまま使えると誤解してました。
elisp manual... なぜ R5RS を読みませんか?
732 :
デフォルトの名無しさん :02/11/17 18:29
それはor使えば?
(loop (or ...))みたいに。
>>732-733 いや、分岐するところが無茶苦茶沢山あって、
最後が末尾ループする(しない場合もある)様にしたいんです。
>>721 みたいにor使ってジャンプテーブルみたいに
ならないかなーと思ったんです。
(or(and ...(loop ...))
(and ...(loop ...))
(and ...(loop ...))
(and ...(loop ...))
...
)
こんな感じで、
末尾再帰にならない以外はorでうまくいってました。
なんかえらくメモリ食うなーと思ったら使い方間違ってた
というわけです。
つまり
>>734 のandとloopの間にletとか色々置きたいわけです。
今condと=>の列に書き直してます。
分岐があって末尾再帰するんならcondかcaseでしょう。 条件が真の場合の答えをそのまま使うっていうんなら (cond ((...) (loop (or ...))) (else ...)) みたいに組み合わせて書ければいいとおもうけど・・・
(cond ((let ((...)) 条件) => loop) ....)
>>736 どうしても条件の結果をそのまま持ってきたかったという
事情がありました。
具体的に言うとパターン判定で真の時マッチした各パーツをもらってきて
letに割り当てる(マッチしなかったら#fを返す)マクロを組んで使って
たので、こうなりました。
(or
(pattern-match-let (変数 a b c) (パターンマッチ式) ;一致したら変数に格納される、失敗=>#f
ここで変数 a b cを使う
(loop ...)) ;ここで末尾ループしたい
(pattern-match-let (変数) (パターンマッチ式)
....
(loop ...))
;
;
)
これをしょうがないので、
(cond
((pattern-match-let (変数) (パターンマッチ式) ;一致したら変数に格納される、失敗=>#f
ここで変数を使う
)=> loop)
((pattern-match-let (変数) (パターンマッチ式) ;一致したら変数に格納される、失敗=>#f
ここで変数を使う
)=> loop)
:
:
に直してます・・・
(define-syntax match-let (syntax-rules (unquote) ((match-let ((unquote var) exp) body ...) (let ((var exp)) body ...)) ((match-let ((a . d) exp) body ...) (let ((v exp)) (match-let (a (car v)) (match-let (d (cdr v)) body ...)))) ((match-let (item exp) body ...) (if (eqv? 'item exp) (begin body ...) (error "Match failure:" item exp))))) これで、 (match-let ((if ,condition ,then ,else) form) form) とやると、Chez Schemeに Error: invalid syntax if. といわれてしまいます。マッチしたいのがSchemeのシンタックスキーワードだと だめみたいなんですが...
すんません。最初の説明が抜けてました。 便乗して聞きたいんだけど、 おれもパターンマッチする束縛構文をマクロで書いてみて うまくいかないんです…
741 :
デフォルトの名無しさん :02/11/17 19:05
(loop (or (pattern-match-let (変数) (パターンマッチ式) ;一致したら変数に格納される、失敗 =>#f ここで変数を使う ) (pattern-match-let (変数) (パターンマッチ式) ;一致したら変数に格納される、失敗 =>#f ここで変数を使う ) ...)) でいいんちゃう?
(rxmatch-let (rxmatch #/(\d+):(\d+):(\d+)/ "Jan 1 23:59:58, 2001") (time hh mm ss) (list time hh mm ss)) => ("23:59:58" "23" "59" "58") 関係ないかもしれないが gauche にはこんなのがある。
>>741 ある条件でループしたくないときもあるんです。
(cond ((or パターンマッチ パターンマッチ) => loop) (ループしたくない ...) ((or パターンマッチ パターンマッチ) => loop) (else ...)) こんなかんじか・・・あんまり美しくないな。
>>739 (match-let ((if ,condition ,then ,else) form) form)
は、(match-let ((if ,condition ,then ,else) form) (list condition then else))
の間違いでした。
>>744 でも、パターンにifとかquoteとかlambdaとかを与えない限り
ちゃんと動くんですよ…
たとえば、
(match-let ((my-if ,condition ,then ,else) form)
`(cond (,condition ,then) (else ,else)))
とすると、ちゃんと動きます。
>>746 マクロの展開の仕方の違いかもしれないですね。
(match-let `(if ,condition ,then ,else) ...)
こういう構文になおしてみては?(明示的にq-quoteを置く)
>>747 うーん。どんな場合でも動かなくなってしまいました。
>>748 これはうちで使ってるやつです
(define-macro (pattern-match-let meta ptn tst . body)
(let ((r (gensym)) (m meta))
`(let ((,r (match ',m ,ptn ,tst)))
(and ,r
(let ,(map (lambda (x)
(list x (list 'list-ref r
(memq-pos x m) )))
m )
,@body )
))))
こんな感じで使います
パターンはquoteまたはq-quoteで括ります。
(match-let (args body params) '((lambda args . body) . params) マッチさせたい式
...処理(args body paramsに一致したパターンが入ります。)
)
750 :
デフォルトの名無しさん :02/11/17 20:32
>>734 構造を変えたくなかったら、loopを継続にしたり、loopをclosureで
包んで落としてorの上位で呼び出すとか。
751 :
デフォルトの名無しさん :02/11/17 21:48
>>749 やっぱり define-syntax は糞という事でよろしいですか?
syntax-rules がショボいだけです。
>>752 syntax-rulesの機能がショボい?
>>739 の書いたsyntax-rulesがショボい?
754 :
UBASICER :02/11/18 03:30
Franz Lispで書かれたSIRがClispで走らない。。。鬱 これってどっちもCommon Lispですよね?
SIRってなんでありますか、サー!
756 :
デフォルトの名無しさん :02/11/18 03:33
Semantic Information Retrievalです。 質疑応答の基礎研究プログラムのようです。 共立出版「Lispによる人口知能の基礎技法」に載っている、 プログラムなのですが。
Franz Lisp は Commonn Lisp より前にできたと思うけど。
つまりFranz Lispの方言でひっかかっていると言う事ですね? でも、Franz Lispで検索しても行きつくところはACLなんですよねぇ。 どなたかFranz Lispの実行ファイル落ちてるとこ知りませんか?
>>759 Common LispでないFranz Lispは(Sun 3に移植されたという噂もあったが)
基本的にBSD 4.x on VAX-11でしか動いていなかったと思う。
761 :
デフォルトの名無しさん :02/11/18 04:15
syntax-rulesやsyntax-case形式をdefine-macro形式に変換する プログラム無いですか? (expand '(define-syntax ...)) =>(define-macro ... ) みたいな感じで使えるやつ
>>760 cygwinでは無理なのでしょうか?
あるいは、Windowsに移植された物は存在しないのでしょうか?
>UBASICER ソースってどれぐらい大きいの? 走らない、だけじゃわかんないよ。 処理系固有部分潰せばなんとかなるかもしれないし。
今うpします。
766 :
デフォルトの名無しさん :02/11/18 06:34
>>765 見た感じpath fexprって部分かな。
fexprってなんだっけ。マクロの前身の様なやつだった気がするけど。
>>766 親切に感謝します。
>>757 の本によるとfexprは任意の数の引数を取ることが出来て、
これらの引数は、評価されずに関数に渡されるとあります。
かっこの対応づけがおかしかったよ。 path fexprはエラーがでた。 動かしてみたらrepeatがないって出てる。
>>768 CLispでの実行結果ですか?
かっこの付け忘れ?←恥
fexprはCommon Lispには無いですね。
Franz Lisp でもちゃんと動いているのだろうか? (defun sir ()の (eq (car s 'Bye) -> (eq (car s) 'Bye) に (defun tests (rule) (ceddr (rule))) (defun action (rule) (cadddr (rule))) かっこ増やしたけど ceddr ってなに? (cadddr rule) が正しいのではと思う。
ここでタイプミスしてました。 prog (l)とするべきところを plog (l)としちゃっています。 (defun apply-tests (tests phrases) (prog (l) (cond ((and phrases (repeat while tests (setq l (cons (apply (car tests) (list (car phrases))) l)) while (car l) (setq tests (cdr tests)) (setq phrases (cdr phrases)) until (and (null tests) (null phrases)))) (return (reverse l))) (t (return nil)))))
なんかgenelic-genelic (おそらくgeneric-generic)とか
スペル間違ってるっぽいし、多分動かした形跡無いな。
OCRで取りこんだとしてもこんな間違い侵すことないだろうし。
本の様な媒体から手で書き写したなら納得かも。
どこから持ってきたの?
>>765
>>770 (defun pattern (rule)
(car rule ))
(defun variables (rule)
(cadr rule))
(defun tests (rule)
(caddr (rule))
(defun action (rule)
(cadddr (rule))
これが正解です。重ね重ねスマソ
CLisp入れて動かしてみたんだけど CLispの設定もうまく出来てないんで私は降ります。 memq入ってないし・・・ repeatはCommon Lisp に入っているの?
>>774 Franz Lisp ってfuncallしなくていいの?
pathは (defmacro path (&rest x-rels-y) (member (eval (caddr x-rels-y)) (path1 (list (eval (car x-rels-y))) (cadr x-rels-y)))) でいいと思う。 中で呼んでるevalが怪しいけど。
ここまでデバッグしたものをうpしなおしておきました。
>>775 乙彼様です。
>>776 実は私もFranz Lispに触った事が無いんです。
>>775 repeatはCommonLispにあるよ。
構文が正しいかは調べてみないとわかんないけど。
>>780 えっ本当ですか?
学術目的なので問題無いです。
感謝いたします。
私は、タイプミスが無いかもう一度本と照らし合わせてみます。
>>777 ここですね?
(defun path fexpr (x-rels-y)
(member (eval (caddr x-rels-y))
(path1 (list (eval (car x-rels-y))) (cadr x-rels-y))))
昔のソースをCommon Lispで動かすときに、一番はまるのが 比較関数だと思う。 昔の(memq x y) --> (member x y :test #'eq) 昔の(member x y) --> (member x y :test #'equal) assocとかunionとかも同じ。:testを加えないと意味が変わってしまう。
condに直すのやめて、
>>750 のclosure作る方法にしました。
ネストの深いor-andからcondに直そうとすると、else節の処理
ロジックを大幅に書き換えないといけないので。
↓最下層のorでクロージャを呼び出す
((or (and ...(lambda()(loop ...)))
(and ...(lambda()(loop ...)))
(and ...(lambda() ...)) ;loopしないとき
...))
という具合です。
786 :
デフォルトの名無しさん :02/11/20 07:31
haskellみたく、lambdaを\で書いてる人いない? (define-macro (\ . x)(cons 'lambda x)) (define series (\(n)(let x((n n)(k(\(x)x)))(if(zero? n)(k n)(x(1- n)(\(x)(k(+ x n)))))))) (series 10) =>55
788 :
デフォルトの名無しさん :02/11/21 11:33
初学者です。 Gaucheを使ってThreadの勉強したいんですけど、なにか良いサンプル を教えてください。
789 :
デフォルトの名無しさん :02/11/21 15:06
790 :
デフォルトの名無しさん :02/11/21 18:13
Digital-MarsのC/C++コンパイラを使ってSchemeを実装してみたいと思ってい ます。どのSchemeのソースをベースにしたら良いと思いますか? 最適化云々 よりも、読みやすいソースが嬉しいです。
Guile以外
>>790 個人的には CAMPUS LIsP が読みやすいな。
(Scheme じゃないけどおんなじようなもんでしょ。)
read, eval, print が別関数になってるところとかが。
minischeme は 1個のループでやってるのと goto もどきを多用してるのでおっ
かけるのがしんどい。でも参考になる関数がたくさんあるのでパクるのが吉。
gauche, guile, scm とかプロな人達の処理系は俺には難しいので眺めるだけ。
あと
>>577 とか
>>18 のサイト見てデータ構造だけプロっぽくしてみたり。
…というのは自分がやってることだったりして。
On Lisp ですが、やっとマクロのところ(19 章まで)を読み終わりました。 マクロの実際の動作や使い方、落し穴などがとても丁寧に書いてあって、 だいたい理解できたと思います。(つもりなだけかも知れないけど。。。) Lisp のマクロは実行されるタイミングが違うだけで、基本的に手続き的な 考え方で理解できますよね。 ところが、20 章の Continuation のところで、いきなりつまずきました。 Continuation とはいったい何なのか、さっぱり分かりません。そこで、 Continuation について分かりやすく解説した本や web page を教えて ください。
(foo foo hoge foo foo) (lambda (x) (foo foo x foo foo)) (begin foo foo hoge foo foo) (lambda (x) x foo foo) (begin foo (foo hoge foo) foo) (lambda (x) (foo x foo) x) 呼び出されたときの継続は無視する。
過去ログ嫁。
>>793 schemeでの継続というのは、制限の緩いgotoラベルみたいなもの。
call/cc(call-with-current-continuation)は、その場所の継続を、
指定された関数の引数に入れて呼び出す関数。
(let ((resume #f)) ;継続を保存する変数
(define (call-cont cont) (set! resume cont)) ;継続を保存する関数
(call/cc call-cont) ;call/ccで継続を取り出す。
(display 'next)
;この継続(resume)を括弧で括って呼び出すと、call/ccが呼び出された次の地点に制御が移る。
;この場合、(display 'next)の位置。
(dotimes 10 (resume)) ;10回繰り返す
#t
)
nextnextnextnextnextnextnextnextnextnextnext
=>#t
;;最初の呼び出しと合わせて11回nextが出力される。
あ、dotimes なんて無かった。
多分
>>797 は無限にnextが出力されると思う。
>;この継続(resume)を括弧で括って呼び出すと、call/ccが呼び出された次の地点に制御が移る。 これ、正確にはcall/ccの呼び出し直後ね。 継続呼び出しには引数を入れる事ができて、その引数が継続の戻値になる。 (let ((resume 'dmy)(result 'dmy)) (set! result (call/cc (lambda(c)(set! resume c) #f))) (display (if result "継続が呼び出された" "resumeに継続を代入")) (newline) (if (not result) (resume #t)) ;引数付きで呼び出し ) 実行結果 resumeに継続を代入 継続が呼び出された
((call/cc call/cc) (call/cc call/cc))
801 :
デフォルトの名無しさん :02/11/23 03:47
すみませんが質問です。 gclのMS-DOS版 www.vector.co.jp/soft/dos/prog/se014703.html を実行しようとしたら、 Error: Can't expand pathname ~/_gcl Fast links are on: do (use-fast-links nil) for debugging Error signalled by PROBE-FILE. Broken at PROBE-FILE. Type :H for Help. >> というエラーメッセージが出てしまいました。 設定はあっていると思うのですが。。 誰か解決法が分かる方がいたら教えて下さい。 よろしくお願いします。 OSはWin98SEです。
>>801 MS-DOSにはホームディレクトリという概念が無いので
~/ が展開できないのではないでしょうか?
>>793 継続、バックトラック、大域脱出、コルーチン、あたりで検索するよろし。
お勧めのLISP本てなんですか?
>>802 え?Unix系だと、open("~/.bashrc", ...)とか直接かけるの?
環境変数HOMEを設定すれば良いのでは。
>>796 それ読んで思ったのは、「どうやら自分は、構造化プログラミングの
考え方に束縛されてるらしい」ってこと。構造化される前の BASIC や、
機械語のレベルまで戻って考える必要があるみたいです。ひさしぶりに
フローチャート書いてみようかな。
>>797-799 「継続を呼び出すとcall/ccが呼び出された次の地点に制御が移る。」
とのことですが、その後どうなるかが分かりません。継続を呼び出した
側には、いつ制御が戻るんですか?(もしかして、戻らないのかな?)
あと、継続を呼び出す時に渡す引数の意味は?
>>806 そおいえばむかし見た記憶が。。。
>>793 >継続を呼び出した側には、いつ制御が戻るんですか?
戻りません。呼びっぱなしになります。
>継続を呼び出す時に渡す引数の意味は
Cのlongjmpに渡す引数と似たようなものかと。
継続を知るには、call/ccから入るよりも継続渡しスタイルを
理解するのが良いと思われ。
読んでみました。「継続渡しスタイル」って、もしかして iterator みたいなもの?(違うんだろうなぁ。。。) で、call/cc に戻りますが、「継続を呼び出したら戻ってこない」 ってことは、じゃぁ制御はどこに行ってしまうのでしょうか? scheme の toplevel で実験する限り、継続の実行が済んだら toplevel に「戻ってくる」ように見えるのですが、実際の プログラムでは、toplevel に戻られても困りますよね?
call/cc を呼んだところに飛んでくだけ。 toplevel で call/cc したなら toplevel に戻って終了。 それだけのこと。
あ、「call/cc が引数付き goto」ってのは正確じゃないかな。
トップレベルで何か式を評価するときの継続は、 「評価結果の値をプリントし、次の式を入力するループへと続く継続」 になります。(print-read-eval continuationとかPRE continuationとか言われる。) トップレベルから (call/cc (lambda (c) ...)) でcに入るのがPRE continuationです。cを呼び出すと、その値がプリントされ、 次のトップレベルループへつながることになります。 (call/cc (lambda (c) (begin (c #t) (display "returned from cont")))) とやってみると、cの呼び出しからは戻ってきていない("returned from cont" は表示されない)ことが分ります。
継続とは「実行のコンテキスト」です。 Cならjmp_bufに保存されるようなもの。あるいはスレッドとして表現 されるようなもの。 継続を呼び出すと、C風に言えば、「今の実行のコンテキストを捨てて、 他のコンテキストにスイッチする」ことになります。
>>814 call/cc の中で継続を呼び出すのは、C 言語の setjmp/longjmp と
同じことだと思うので、それは分かるんです。(たぶん)
でも、call/cc を抜けてから継続を呼び出すことは、どう理解すれば
良いのやら。。。
あまりいいたとえじゃないのでしょうけど、call/cc の中で継続を
呼び出すのって、未来にタイムスリップすることのような気がするんです。
つまり、10 分後の未来にタイムスリップすれば、自分は 10 分間存在
しなくて、その間に起こってたことを知らない、と。でも、call/cc を
抜けてから継続を呼び出すと、過去にタイムスリップしたことになって、
タイムスリップする前の自分と、したあとの自分が同時に存在する状態に
なる、ような。。。
なんか、根本的に理解できてませんね。自分が情けなくなってきました。
817 :
デフォルトの名無しさん :02/11/23 15:56
便乗で質問。 引数作成中とか、letのバインドの最中の継続を取ってきて、 あとでその継続を呼び出す事ってやっていいの?
setjmp/longjmpと確かに似てるね。
setjmpへの最初の呼び出しで得られる「その時点でのコンテクスト」は
基本的に1回しか(longjmpで)使えないが、継続の場合は何回でも呼び出して
「その時点」に戻れる。
Cの局所変数が、関数から戻ると消えてしまうのに対して、Schemeの変数は
必要な間 ずっと残っているのに似ている。
>>817 もちろんかまわない。Schemeの場合、変な例外や制限はほとんど無い。
>>818 え、いいの?
例えば、
(define baz '())
(define (bar)(call-with-current-continuation(lambda(cont) (set! baz cont) 2)))
(define (foo a b)(display(+ a b)))
(foo (bar) 1)
(baz 3)
(baz 4)
;とかやって、継続を呼び出すと、上手く行かない
処理系があると思うけど。試した限りでは、
SCMは駄目、
petiteは出力345(意図通り)
qschemeやgaucheでも誰か試して欲しいです。
ヤッタァァァァァァァァァァァァァァァァァァァァァァ!! 初めて2ゲットォォォォォォォォォォォォォォォォォォォォォォォ! 2ですよ2!!そう簡単に取れる モノじゃないですよコレは。 本当にウレシイよ!!!
SCM5d2も345と出力されるけど? 例外はあんまりないんだけど、トップレベルの継続はまあ 例外といってよいかも。どういうのが「正しい」動作かはなかなか 難しい。 たとえば、819のコードで最後を (begin (display (foo (bar) 1))(newline) (display (baz 3))(newline) (display (baz 4))(newline)) と同じだ、と解釈すべきなのかどうか? もしそうだとすると、345という出力は正しくないことになる。 あるいは、上をファイルに書いておいて、ロードするとしたら 正しい動作は何なのか?
あれ?うちが試したのはSCM version 5d4です。
あ、let付けてました。
ようするにいろいろ(スタックとか)やってくれるジャンプ。
>>823 >あ、let付けてました。
んじゃたぶん 344444.... になるんでは?
(baz 3) を呼んだときに実行位置が (foo (bar) 1) に戻されてしまって無限ループ
826 :
デフォルトの名無しさん :02/11/24 18:48
コマンドラインでインタプリタ使う向けに 1行エディタみたいなの無いですか? シンボル補完もあれば尚よし。
libreadlineが定番では。 シンボル補完ができるのかどうかは知らん。
>>802 >>807 HOMEを設定したら起動できました。
オプションかのように書いてあったけど、
設定しなきゃいけなかったんですね。
ありがとうございました。
>>827 readlineてwindowsでも使えるのかなあ。
無理矢理Cのconioライブラリとかをscheme側へ引っ張ってきて、
getch相当と、カーソルの位置取得/設定があれば動作する様に
作ってます。フリーカーソル行編集と入力ヒストリもどきを作って
一息つきました。
で、これ良く考えたらreplの中(プロンプト辺りをすげ替え)で動作
させる必要があるのに気付いた。鬱。
830 :
デフォルトの名無しさん :02/11/25 09:38
質問なのですが、みなさんは関数論や計算論をやってる内に、Lispやschemeに たどり着いたのでしょうか?それともLispやschemeをやっていて、その次に 関数論や計算論を学んだのでしょうか。
関数論って言うと、プログラミングとは余り関係のない数学の分野を指します。計算論というのも、オートマトンとかチューリングマシンとかを言うことが多 いような。 プログラミング言語理論とかラムダ計算とかの意味なら、私の場合は「Lispが 先」です。
>>786 CommonLispだと\はマクロ文字とかのエスケープ記号だから、
\(と書くと(というシンボルになるんじゃないかと。
やっぱ自分の錯覚でした。 なんで勘違いしたんだろう・・?
オレは何の気なしに「プログラミング言語ML」を買って、それで関数型プロ グラミングを知り、それでSchemeにたどり着いた。あ、しかし、それ以前か らEmacsとEmacs Lispは使っていたな。
Chez Scheme 6.0の見積もりを取ったが、いやはやあんなに高いとは。 マシン・タイプごとに24,500ドル。サポートが1機種 年間1,350ドルだと。 それほどの価値があるソフトなのか???
サポートの方は、まあ妥当なんじゃないかな。月あたり100ドルちょっとだから、 まあ、そんなもんじゃないかと。 24,500ドルの方は...たしかに高いけど、ランタイムは無料なわけじゃない? というより、パフォーマンスを問題にしないのであればPetitで良いわけで、 パフォーマンスを問題にするようなコードをCではなくLispでもなく、あえて Schemeで書くというのは、どうしてもSchemeでないと困るようなニーズがある のだと推測しますが、だったら選択の余地なく購入するのでは。 # 納期が問題でないならSCM+Hobbitで満足できるだろうし。
あと、きっと相談すれば試用できると思う。
838 :
デフォルトの名無しさん :02/11/26 09:30
最近、schemeを始めて非常に初心者的な質問なんですが、 schemeの関数はリストそのものを引数として評価したい場合 クォートするじゃないですが、(length '( 1 2 3))って感じで。 でも、このクォートを使わず、(my-length (1 2 3))って評価できるような 関数・拡張シンタックスって定義することは出来ますか?
(define-macro (my-length l) `(length ',l))
840 :
デフォルトの名無しさん :02/11/26 10:58
ISLISP って何て読むの?
リスプです。
>842 International Standard LISPの略
>>843 あ、それは知ってるの。
その上で ISLISP って皆さん何て読んでるのかなって思ったの。
愛エスリスプ とか
イズリスプ とか
毎回 International Standard LISP って読むのは冗長でしょ?
(`毎回' というほどの頻度は無いというのはおいといて)
840が正解(ISLISPの読み方)を知るまでの道はまだまだ険しい。
Continuation、やっと分かりました。要するに、goto なんですね。(笑) 「呼び出したら、必ず呼出し元に帰って来る筈」という構造化プログラミングの ジュバクに捕らわれていたみたいです。toplevel で呼び出すと、toplevel に 帰ってくるように見えるし。 R5RS を読んで、 ・末尾再帰も継続呼び出しと同じメカニズムで実現されていること ・dynamic-wind と継続呼び出しとの関係 あたりですっと納得したようです。まぁ、他にもいろいろ読んで、頭をほぐして おいたせいで理解できた部分もあるとは思いますけど。 Continuation について教えてくださったみなさん、ありがとうございます。 # そうそう、call/cc が関数を引数にとる関数なのも混乱を助長した部分が # あると思います。On Lisp では、そういう場合はマクロを使えと徹底的に # 書いてありますから。あと、継続が関数なのも分かりにくい。継続が独立 # したオブジェクトで、(goto-continuation cont arg) みたいに書く # ようになってたら、こんなに悩まなかった、、、かもね。
>>846 基本構文の種類や基本データタイプの少なさはSchemeの自慢なので、
なるべく増やさないようにしていると思われ。
最初のSteeleらのSchemeでは(call/cc (lambda (c) ...))でなく
(catch c ...)と書いていた。
>>845 えっと、`IS' も含めて
リスプ
って読んじゃうの?
849 :
デフォルトの名無しさん :02/11/26 14:27
継続呼び出したりするコードって、 「参照透過性が良い」って言うんだろうか?
同じ引数に対して同じ結果を返すなら Referencially transparent でそ.
>>850 CPSだと関数は値を返さないけど、そういう場合は?
853 :
デフォルトの名無しさん :02/11/26 15:26
>>846 > 継続が関数なのも分かりにくい。継続が独立
> したオブジェクトで、(goto-continuation cont arg) みたいに書く
> ようになってたら
そうだね。SMLでは継続は別オブジェクトなんだっけ。
まあ、tail callのことを考えると関数と継続を区別する必要は無いって
理屈なんだろうけど。CPS conversionしたら同じだし。
値と継続って双対性があるよね。 半導体の「電子」と「ホール」の関係。 だから、継続を特殊なデータ型と考えるのはおかしい。
タレか ISLISP の読み方おせーて ・°・(ノД`)・°・。
アイエスリスプ。
イズリスプ。
ISLISP (´・∀・`)ヤター
island → アイランド islisp → アイリスプ
愛得洲リスプだよ。設計者が言ってたから間違いない。
伊豆リスプだよ。実装者が言ってたから間違いない。
>>859 さんありがとう♪
これでやっと今夜はグッスリ眠れます。
( ̄ー ̄)ニヤリッ
>>864 ,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,--―'''""`ヽ'  ̄`ヽ、
/ ヾ / ~`ヽ
/ ヽ;: /"""ヾ ヽ
/ ;:;;:::'''' l /;:;;:::''' \ i
/ /;:;;:::''' ヽ ヽ
| | ヽ |
/ ;/ ヽ ヽ
/ ;:;:ヽ ,,,,;;::'''''ヽ |
i / ,,,,;;::::::::::::::: __ ヽ ヽ
| | " __ :::: '"ゞ'-' | |
| |. - '"-ゞ'-' ::::::.. |. |
| ;:| ::::::: | :|
| ヽ. ( ,-、 ,:‐、 | |
| /ヾ.. | |
| | __,-'ニニニヽ . | |
.. | `、ヽ ヾニ二ン" / |
| ヽ\ / |
| l `ー-::、_ ,,..'|ヽ./
ヽ. :人 `ー――''''' / ヽ
/;:;:;:;;:;:;: _/ `ー-、 ,.-'" \ー-、
,.-'" \: \ .,.-''" |
/. \ ~>、,.-''" |
,,..-‐'''"" ヾ ,.-''"| /――――、/
ISLISPをISLISPと読める人でないと
(ISLISPを使うのは)難しい(w
868 :
デフォルトの名無しさん :02/11/27 23:27
870 :
デフォルトの名無しさん :02/11/28 11:13
kawa schemeで次のコードを実行すると、 結果を出さずに終了してしまいます。 何が原因でしょうか。(試してるのはJ2SE1.41上です。) このコードでスタックオーバーフローが起きるとは思えないんですが・・ ---------cpsfib.scm----------- (define (cps-fib n) (let loop ((n n)(k(lambda(x)x))) (cond ((= n 0) (k 0)) ((= n 1) (k 1)) (else (loop (- n 1) (lambda(l) (loop (- n 2) (lambda(r) (k (+ l r)))))) )))) ---------cpsfib.scm----------- java -cp kawa-1.6.99.jar kawa.repl #|kawa:1|#(compile-file "cpsfib.scm" ""cpsfib") #|kawa:2|#(load "cpsfib") #|kawa:3|#(cps-fib 30) java.lang.StackOverflowError at gnu.math.IntNum.add(IntNum.java:404) at gnu.math.IntNum.add(IntNum.java:1378) at gnu.kawa.functions.AddOp.apply2(AddOp.java:34) : :
871 :
デフォルトの名無しさん :02/11/28 11:52
lambdaの使いすぎかなあ。
解決しました。 kawaマニュアルの「制限」の部分に載ってました。 java.exe -cp kawa-1.6.99.jar kawa.repl --full-tailcalls これでうまくいきました。 末尾再帰じゃない方のfib (define (fib n) (cond((= n 0) 0)((= n 1) 1)(else (+ (fib (- n 1))(fib (- n 2)))))) は--full-tailcallsを付けないでokでした。 ただし、--full-tailcallsを付けると、末尾再帰じゃない方のfibとか も影響受けるのか、多少遅くなるみたいです。 デフォで--full-tailcallsを付けた方がいいのか、 なんか微妙ですね・・・。
(define (fib n) (let iter ((x 0) (y 0) (z 1)) (if (= x n) y (iter (+ x 1) (+ y z) y)))) (define (fib n) (do ((x 0 (+ x 1)) (y 0 (+ y z)) (z 1 y)) ((= x n) y))) (define (fib n) (let iter ((a 1) (b 0) (p 0) (q 1) (n n)) (cond ((= n 0) b) ((even? n) (iter a b (+ (* p p) (* q q)) (+ (* 2 p q) (* q q)) (/ n 2))) (else (iter (+ (* a (+ p q)) (* b q)) (+ (* b p) (* a q)) p q (- n 1))))))
>>871 たぶん動的に生成したlambdaクロージャは末尾再帰の対象に
ならないのが原因だと思いますが、--full-tailcallsを付けない場合でも、
named-letは末尾再帰してる様です。(特別扱い?)
なんで自動で切り分けしてくれないんだろう。
動的に作成したclosureを返すコードがある→--full-tailcallsの適用
静的なclosure(=関数)しかない→--no-full-tailcallsの適用
でいいと思うんですが。そこまで解析してないのかな。
次のコードは--full-tailcallsを付けないと スタックオーバーフローです。 (define (x)(y)) (define (y)(z)) (define (z)(x)) (x) または (define (w) (letrec ((x (lambda()(y)))(y (lambda()(z)))(z (lambda()(x)))) (x))) (w) --full-tailcalls必須かなー。
皮スキム
kawaは、SchemeをJVMのバイトコードにコンパイルして実行する わけだが、JVMの命令には、他の関数(正確にはメソッド)を tail-recursiveに呼び出すような命令がない。 同じメソッドの中ならgoto命令で飛べるので、局所関数なら わりと簡単にproper tail recursionを実現できる。 任意の関数呼び出しをproperly tail recursiveにするには、 トップレベルにトランポリンが必要になり、少し遅くなる。
ウレタンスキム
qschemeって、closure作る度に環境を根元まで複製してるみたいだけど、 遅くならないのかな。(vm2.c:mk_persistent_env辺り) CPSみたいなコードだとやたら遅くなる気がする。
>>881 cpstakってなんですか?名前からして*nix系のコマンドかな。
今windowsしかないんで、ソース見てあーだこーだやってるだけです。
mingwで動けば良いんだけど、configureが。。
>>882 cpstakは、Gabriel benchmarkというベンチマークの中の1つです。
;;; CPSTAK -- A continuation-passing version of the TAK benchmark.
;;; A good test of first class procedures and tail recursion.
(define (cpstak x y z)
(define (tak x y z k)
(if (not (< y x))
(k z)
(tak (- x 1)
y
z
(lambda (v1)
(tak (- y 1)
z
x
(lambda (v2)
(tak (- z 1)
x
y
(lambda (v3) (tak v1 v2 v3 k)))))))))
(tak x y z (lambda (a) a)))
(do ((i 0 (+ i 1))) ((= i 1000))
(write (cpstak 18 12 6))
(newline))
cpstakをやってみると、確かにqschemeは遅いです。 petiteの2.7倍くらい時間がかかっている。
885 :
UBASICER :02/12/01 07:07
>>804 Guy L.Steele Jr.著 井田昌之 翻訳監修
COMMON LISP 第2版 共立出版
でもこの電話帳高いよん ♥
887 :
UBASICER :02/12/01 08:49
いや!この本持ってまつ。♥ ♥
888 :
UBASICER :02/12/01 08:50
888get♪ さあて パチソコ逝こっと
define-macro ではできるけど define-syntax + syntax-rules ではできない、 またはその逆ってありますか?
891 :
デフォルトの名無しさん :02/12/01 19:09
>>889 両方とも可逆変換出来るはず。
でも、syntax-rulesはなんか制限あった気がする。
>>890 なにが#t?
892 :
デフォルトの名無しさん :02/12/01 19:38
>>889 素直にやると、syntax-rulesではimplicitに変数を捕捉することが出来ない。
例えばOn Lispにあるaifやawhileでボディの "it" が自動的に束縛される
ケース等。もともと、define-syntaxはマクロの使用環境の変数束縛と
定義環境の変数束縛が干渉しないように設計された。hygienicなマクロという。
ただ、define-syntaxで暗黙の変数束縛が絶対にできないかというと、
実はそんなことはなくて、R5RSマクロは通常のSchemeと等価である
ということが示されている。
http://okmij.org/ftp/Scheme/macros.html 但し、かなり技巧的。letやlambdaをローカルマクロで再定義したり
する。普通にマクロを使っているぶんにはhigienic
な性質が破られることはないだろう。
define-syntaxの何がうれしいのか全く理解できん。 Common Lisp等のdefmacroから、ものすごい改悪をしたと思う。 たぶんhygienicという宣伝文句を使いたかったんだろうが、 複雑・面倒にしただけ。
>>893 意図しない Variable Capture によるバグが出にくくなるのが
メリットなんじゃない?
その通りでござる! On Lisp を読むでござる! などと言ってみる。ちなみに今そこらへんを読んでるところです。
マクロによって導入される変数束縛がマクロ使用時の変数束縛と 干渉してしまう点に関しては、gensymをちゃんと使えばほとんど 問題にはならない。 個人的にはむしろ、グローバルなidentifier (lambda等の syntacticなkeywordやら、list等の標準手続き等) がaccidentalに 使用環境での束縛によってシャドウされないことが嬉しい。 マクロのモジュラリティが増すからね。 (define-syntax foo (syntax-rules () ((_ args ...) (list args ...)))) (let ((list length)) (foo 1 2 3)) => (1 2 3) これはdefine-macroでは素直には出来ないでしょう。 ただ、hygienic macroでもマクロを定義するマクロを持ち込む ことで、見掛けのhygienityが壊されることを示したのがOlegの記事。
でも、Common Lispのdefstructやloopを define-syntax使って書く気にはなれないなあ...
>>896 >(define-syntax foo (syntax-rules () ((_ args ...) (list args ...))))
>
>(let ((list length)) (foo 1 2 3)) => (1 2 3)
これが利点だというのがおかしい。
初心者には非常に分りづらいでしょう。
「マクロというのは、S式からS式への変換規則だ」
と教えるだけで話がすまなくなる。
899 :
デフォルトの名無しさん :02/12/02 12:53
>>896 define-macroで無理やり定義すると、
(define primitive-list list)
(define-macro (foo . x)`(primitive-list ,@l))
ですか?
>(define-syntax foo (syntax-rules () ((_ args ...) (list args ...))))
>
>(let ((list length)) (foo 1 2 3)) => (1 2 3)
これをfooについてだけexpandするとどうなるの?
>>892 にあったコードが gauche だとエラーになるけどこれはバグ
でしょうか?
% cat macro.scm
(define-syntax foo-m-fixed
(syntax-rules ()
((_ x)
(let-syntax
((id
(syntax-rules ()
((_ y) y))))
(id (+ x 1))))))
(display (foo-m-fixed 4)) ; prints 5
(newline)
% gosh macro.scm
*** ERROR: unbound variable: y
Stack Trace:
_______________________________________
0 #<id 0x819a860 user::y>
>>898 初心者に判りにくいというのは、そのとおりかもしれない。
そもそも衛生的なマクロは「S式からS式への変換」では無いから、
「リスト操作ができればマクロが書ける」
というLispマクロの利点が無くなっている。
でも Schemeはstatic scopeなんだから
局所的な定義がマクロの挙動に影響を与えるのはイヤ、
という気分も判る。
使う側からすれば、
マクロがどんな風に定義されてるかは気にしたくないし。
define-syntaxの実装はまだバグも多いな。
>>739-751 とか。
使えねー。
>でも Schemeはstatic scopeなんだから
>局所的な定義がマクロの挙動に影響を与えるのはイヤ、
>>896 の例では、defmacroによる定義のほうが正しくて、
define-syntaxの方は、意図と違う結果に展開されてしまった
と感じるのだが。
つーか、「S式→S式の展開結果の字面」で判断できないような
ものをマクロと呼ぶなといいたい。
904 :
デフォルトの名無しさん :02/12/03 08:41
>>903 >defmacroによる定義のほうが正しくて、
マクロ定義を含むライブラリを作った時に、そのマクロ使用時の環境に
制限がかかるのっていや〜んな感じしません?
903の例だと内部のlistの束縛がfooの展開に影響を与えているのは
見ればわかりますが、マクロの定義も使用環境もものすごく複雑化
した時に干渉を見付けるのは相当難しいですよ。マクロだけ取り出して
macroexpandしてみても気づきにくいですし。
もっともR5RSの範囲内だけだと標準ライブラリ関数と同じ名前の
ローカル変数の使用を避ければいいだけなんで、あんまり有難味は
ないんすけどね。
健全性がモジュール(グローバルな名前空間)を含んで解釈される場合、
すなわちマクロ定義時のfreeな束縛はマクロ定義時のモジュールで
解釈される、というふうになっていると、マクロから呼ぶための
補助関数をマクロを定義するモジュール内に閉じ込めておくことが
できます。defmacro形式だと補助関数もマクロ使用者から見えないと
ならないんで名前空間を必要以上に開示するのを気持悪いと
感じてしまうんですよね。
CLだとシンボルそのものにパッケージ情報が付属しているから
defmacro形式でもそんなに問題にならないんですがね。
パッケージシステムはあれはあれではまることがあるから…
などと言いつつ、自分はdefmacroの方をよく使います。
何でもできる柔軟性は捨てがたい。
905 :
デフォルトの名無しさん :02/12/03 09:16
schemeの勉強を始めました。 schemeで書かれたソースを読んでみたいのですが、お勧めはありますか?
906 :
デフォルトの名無しさん :02/12/03 10:26
slibとかライブラリ関連かな。
>>905 GaucheならWiLiKiとかも参考になるかもしれない。
>>906 ,907
お勧めありがとうございます。読んでみます。
909 :
デフォルトの名無しさん :02/12/08 05:52
define-syntaxとかってdefine-macro/defmacroで記述できるの?
911 :
デフォルトの名無しさん :02/12/08 06:06
>>910 じゃ、お願いします。
というか、syntax関係をdefine-macroで記述してる処理系
って何かありますか?
913 :
デフォルトの名無しさん :02/12/08 06:21
>>912 それらしいのがありました。
r4rsyn.scm
synrul.scm
この辺りですかね。
なんか今まで見落としてました。
914 :
デフォルトの名無しさん :02/12/11 00:56
寂れてるな。 lisperは冬眠ですか?
PrologスレでなぜかLispネタが。
916 :
デフォルトの名無しさん :02/12/11 01:26
( ● ´ ー ` ● )なっちも仲間に入れてよう
(define ´ #f) (define ー #f) (define ` #f) (define ● #f) (define ( ● ´ ー ` ● ) (display "なっちも仲間に入れてよう\n")) ( ● ´ ー ` ● )
>(define ● #f) これはいらないや。
919 :
デフォルトの名無しさん :02/12/12 12:48
920 :
デフォルトの名無しさん :02/12/13 20:31
どなたか「Scheme手習い」を譲って(売って) 頂けるかたいらっしゃらないでしょうか。 読んでみたいよー。
英語で読もうね。たいして難しくないから。
了解
923 :
デフォルトの名無しさん :02/12/14 04:16
The Little Schemer(Scheme手習い)の話が出たので便乗。 この続編(?)として、「The Seasoned Schemer」という本が あるみたいだけど、これは読む価値ある? 読んだことある人、情報キボンヌ。
>>923 普通に Little Schemer の続き。11 章から始まります。
漏れには読む価値は人それぞれじゃないか?慣れた人なら改めて
読むほどでもないと思うが。
>>924 「漏れには為になったが」と書きたかったんだが、欝だ。
>>924 情報ありがd
さっそく Amazon 1Click しよ
Java…書いていてつらい… Schemeきぼん…ぐはっ!!
928 :
デフォルトの名無しさん :02/12/18 01:56
scheme48の ,symbol argument... って書き方は何なんでしょうか? unquoteじゃないみたいですけど ,(lambda(x) 'a) 1 2 は ((lambda(x) 'a) 1) 2 と展開するのかと思ったんですが、違ったみたいです。
継承とか楽しくない?
( ´∀`)エヘヘ
これスレは、931まで来ながら無きものにされようとしているのかの?
932 :
デフォルトの名無しさん :02/12/20 19:01
それじゃあ余りに不憫なんでageとくわ
933 :
デフォルトの名無しさん :02/12/22 01:26
そろそろ次スレですね(ボソッ
934 :
デフォルトの名無しさん :02/12/24 23:13
教えてください。 実行しているプログラム名(自分自身)を知るための関数って何ですか? 使っているのはGaucheです。 インタラクティブセッションでは、(???) => gosh とでていました。
935 :
デフォルトの名無しさん :02/12/24 23:50
gosh> *program-name* "gosh"
info嫁ハゲ
937 :
デフォルトの名無しさん :02/12/31 03:29
なんか保守が必要なきがしてきた
938 :
デフォルトの名無しさん :03/01/04 01:18
ん、cons.orgが落ちてる?
みなさんニュースグループはどれを読んでます? comp.lang.lispとcomp.lang.schemeは基本ですか?
c.l.lは意味の無い罵り合いが多いな。罵倒語の勉強にはなるけど。 c.l.sはたまにすごく興味深いポストがあるね。 しかしc.l.lとc.l.sと読んでると、LisperとSchemerって仲悪いの?って 感じがする。
流量少ない個々のプロジェクトの ML は gmane 経由でのぞいてます。 c.l.l で出てた CL-SDL とか CL-PDF 使ってる人居る?
943 :
デフォルトの名無しさん :03/01/05 02:34
趣味で LISP の勉強を始めました。 Cygwin を使ってるのですが、 GCL-2.5.0 のコンパイルには失敗し、 ECL-0.8 では謎のスタックオーバーフローが出て困ってます。 これらの解決法、または 他に Cygwin 上でまともに動くフリーの LISP パーサはありますか? 補足) ・GCL unixtime.c でコンパイルに失敗します。 __MINGW32__ が定義されてないと必ずエラーになるようになっていて、 -mno-cygwin つけてコンパイルしようとすると sys/times.h がないというエラーが出てしまいます。 ソースファイル弄くってなんとかコンパイルしても、 別のソースでまたエラーが出てどうにもこうにも...。 ・ECL エラーが発生すると、 > Read or write operation to stream #<input stream "stdin"> signaled an error. > Explanation: Illegal seek. が沢山表示され、最終的に > Unrecoverable error: bind stack overflow. と、スタックオーバーフローになってしまいます。
944 :
デフォルトの名無しさん :03/01/05 03:29
そこ、Scheme の処理系ですよね。
946 :
デフォルトの名無しさん :03/01/05 04:11
947 :
デフォルトの名無しさん :03/01/05 09:19
>>943 Windowsならclispあたりが一番じゃない?
gclにこだわるのはmaximaでも入れるつもりかなあ。
;最近のmaximaはclisp、cmuclでも動くらしい。
実行速度気にするんならallegro買うなり、
Linux入れてcmuclするなりした方がいいだろうけど。
オープンソースで最速っぽいCommonLispは、やっぱcmuclですか? windowsにportされないのはmmapとかunix特有の機能使ってるから だっけ?clispはコンパイルしても(VMだからか)遅かった様な。
趣味でやるだけなので速度はあまり気にしないです。 教えてもらったところなどを色々見ました。 CLISPがCygwinと一番相性良さそうということなので、 CLISPを入れてみました。 Cygwin上でコンパイル済みのパッケージも用意されていていい感じですね。 パッと見動作もおかしくないようで、満足です。 ありがとうございました。
950 :
デフォルトの名無しさん :03/01/06 11:17
SICPの4,5章にしびれました。 さらっと読んだだけなので これから丹念に読み直そうと思っています。 ところでその後はみなさんそのような学習を されたのでしょうか? ソースの公開されている言語処理系を ハックしまくるとかですか? 学習にあたっての参考書籍などがあれば教えて頂きたいです。
951 :
デフォルトの名無しさん :03/01/06 13:31
>951 後半、いきなり人名別になるのがワラタ
953 :
デフォルトの名無しさん :03/01/07 10:29
>952 禿げ同。 Sussmanいないってのが。
954 :
デフォルトの名無しさん :03/01/07 22:17
Emacs Lispとschemeってかなり違うものなんですか?
はい。
956 :
デフォルトの名無しさん :03/01/08 00:23
Cよりは近いくらい?
957 :
デフォルトの名無しさん :03/01/08 14:17
Emacs LispとSchemeの似ているところはS式を使うところくらいだよねえ。 CとJavaが一見文法が似ているくらいの類似かな。
elispはまがい物ですか?
959 :
デフォルトの名無しさん :03/01/08 16:42
末尾再帰と静的スコープがないから プログラムの書き方が違ってくる。
961 :
デフォルトの名無しさん :03/01/08 18:51
>>959 深い再帰計算してるとあぼーんするのか?
(´・ω・`)フゥ…
(´・∀・`) ヘー
967 :
デフォルトの名無しさん :03/01/08 20:26
ホ ┃ ┃ ┃ ┃ ┃ (゚∀゚) ┃ ┃ ┃ ┃ ┃ ┃ ッ !!
ネタスレを立てるにしても9割の悪意と1割の良心を心がけます
最高裁への上告は認められなくなったから、これで事実上判決確定だよ。
逆転も何もないって。
勢いで上告なんかしても一発で上告却下(門前払い)だよ。
二審も一審を支持。これに対して上告しようにも、
刑事訴訟と同様、自由に上告できるってもんでもないのです。
民事訴訟法312条 (上告の理由) 1項
「上告は、判決に憲法の解釈の誤りがあること
その他憲法の違反があることを理由とするときに、することができる。」
http://www.m-net.ne.jp/~doba/goto/hon.htm ようするに上告しても今の制度では100%無駄。 これで完全終了ってことか。
今までの暗黙の了解が公になっただけの話では。
973 :
デフォルトの名無しさん :03/01/09 14:48
======2==C==H======================================================
2ちゃんねるのお勧めな話題と
ネットでの面白い出来事を配送したいと思ってます。。。
===============================読者数: 138720人 発行日:2003/1/9
年末年始ボケがそろそろ収まり始めた今日このごろのひろゆきです。
そんなわけで、年末に予告したIP記録ですが実験を開始しています。
「2ちゃんねる20030107」
こんな感じで各掲示板の最下部に日付が入ってるんですが、
20030107以降になってるところはログ記録実験中ですー。
んじゃ!
────────────────────────Age2ch─
■この書き込みは、Age2chを使って配信されています。
────────────────────────────
Keep your thread alive !
http://pc3.2ch.net/test/read.cgi/software/1041952901/l50 ────────────────────────────
ダウソ住人としては肩身が狭くなっちゃうなー
>>161 qb、live2、tmp 以外にも今後
>>15 の条件を満たす板
って言うつもりだった也。俺も寝た方が良さげだわ。
てかネトヲチもIP取ってたっけねとっくに
漏れ漏れでスマソ
OK. 録音とか(盗聴も) してていいです。 只、そのノイズも国家機関に分析されます。 2分後に掛けます。 自己紹介と、一般の世間話をしたいと思います。 最初に確認したいのですが(深夜で遅いし。用件もあっさり、こってり。一見だし) 「私」青少年が色々と危機的なんです。 「早急に」+、前向きに 色々と検討して下さいますでしょうか。 私は18歳です。其方のプロフィールを簡単に今お願いします!ありがとう。
正直、2ちゃんねるは失いたくないな・・・
個人情報保護法施行なら閉鎖か 今回の事件では警察が摘発する以前に、 容疑者とされる男の住所や実名が2ちゃんねるに書き込まれた。 結果的に事実ではあったが、事実かどうかには関係なく、 その段階では容疑者とされていなかった人物の 個人情報が勝手に書き込まれたことには変わりない。 本人の同意なしの第三者への個人情報提供の 原則禁止を義務付ける個人情報保護法案は、 7月に閉会した国会では成立せず、継続審議となった。 だが、もし個人情報保護法案が施行されれば、 こうした書き込みをしたユーザーや、 書き込みを放置した2ちゃんねる側は、罪に問われることになる。
ハッキリいって、どこもかしこも書き込みなくてつまんねえ。 最近は深夜ツーカ、早朝の書き込みが少なくなってたとはいえ、 おまいら、この程度でなにびびってんだゴルァ 他が安全で、にちゃんが危険になったとでも思ってる、ネト無知ばっかや。
2003年1月9日より 計2731票 匿名性に絡む問題なので反対 27% 763 票 サイトのためになるから賛成 54% 1489 票 利用しないから関係ない 8% 242 票 2ちゃんねるってなに? 4% 122 票 アクセスログってなに? 4% 115 票 みんないい香具師がおおいのか?
マジで騙された・・・
984 :
デフォルトの名無しさん :03/01/10 16:21
こっちは埋め立てた方がいいかな
sage
うっさいへげ
削除しなかったことが問題であって、IP取得は全くの見当違いだと思うんだが それよかズボラな削除体制どーにかしろって感じだな どさくさに紛れて都合の良い法律案を盛りこむ議会みたい 管理批判の多い板から記録してるっつーのもなんだかなあ
釣りじゃないのなら実に現実味のない意見だ
ID導入当時の話だからね。 今はもうないよ。 今のIDシステムは知らないけど、当時は 127.0.0.1の、127.0.0だったか、0.0.1を非可逆暗号化して、表示してた ように記憶してる。 だから、全パターンをデータベース化しちゃえば、解析可能、と。 実際は解析しきってなかったから、「不明」になっちゃう場合が 多かったけど。
鯖代負担、やくざやチョンや企業や政治家もろもろの圧力に負けない、掲示板管理の絶妙さ これらが揃わないと難しい。2chって本当奇跡的だったんだな(´-`).。oO
てゆうか2ちゃんねらー
子供だからわかりませんってほんとに言ったの?>にかいどー氏に
もしかして、zdnetは、ひろゆきの本名を知らない?
埋め
埋め
埋め
埋め
埋め
埋め
埋め
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。