1 名前:デフォルトの名無しさん [2005/05/12(木) 21:44:01 ] 過去スレ Part1: piza2.2ch.net/tech/kako/987/987169286.html Part2: pc.2ch.net/tech/kako/1002/10025/1002584344.html Part3: pc.2ch.net/tech/kako/1008/10082/1008220265.html Part4: pc.2ch.net/tech/kako/1016/10162/1016211619.html Part5: pc3.2ch.net/tech/kako/1023/10230/1023091882.html Part6: pc3.2ch.net/tech/kako/1031/10315/1031560687.html Part7: pc5.2ch.net/tech/kako/1042/10421/1042167213.html Part8: pc5.2ch.net/tech/kako/1058/10582/1058263391.html Part9: pc2.2ch.net/test/read.cgi/tech/1069594582/ Part10: pc5.2ch.net/test/read.cgi/tech/1075630259/ Part11: pc5.2ch.net/test/read.cgi/tech/1091456033/ Part12: pc8.2ch.net/test/read.cgi/tech/1100229366/ 関連リンクは>>2-10 あたり
367 名前:364 mailto:sage [2005/06/16(木) 14:06:31 ] 当方の環境は emacs と xyzzy ですので、新たに手入力をしたりはしていませ ん。*scratch buffer* の同じ行で、C-j を繰り返しています。それでも x は 伸びないのです。 なお、念のため (defun f () (setq x (nconc '(title =) y))) も書いてみま したが、やはり emacs、xyzzy とも x が伸びたりはしません。
368 名前:デフォルトの名無しさん mailto:sage [2005/06/16(木) 14:15:10 ] こうじゃないの? (setq x '(1 2 3)) (nconc x '(4 5)) nconc を繰り返すと x は長くなっていく(@emacs21)。
369 名前:デフォルトの名無しさん mailto:sage [2005/06/16(木) 14:15:44 ] >>367 >C-j を繰り返しています。 これはLispインタプリタ側から見たらテキストを再入力してるのと同じ。 内部的にはトップレベルの (read) がもう一回呼ばれるからね。 ところで y の値には何を入れて試してるの?
370 名前:364 mailto:sage [2005/06/16(木) 14:36:05 ] (setq y 'hoge) としてから実行しています。ちなみに、先の関数 f をバイト コンパイルしても、やはり x は伸びません。 私の疑問をまとめますと、'(title =) を評価したら、それが再度の手入力で あれ、バイトコンパイル後の関数内であれ、毎回新たな cons セルが生成され るのが自然なのではないか、x が伸びるのはおかしいではないか、というもの です。 しかし、よく考えてみると、伸びないのが逆におかしいような気もします。混 乱してきました。 nconc に渡されるものの実体は何でしょうか?渡されるものがただの文字列で、 それを nconc が評価してリストを生成するなら、伸びないのが自然だし、渡 されるものが cons セルそのもので、その生成は最初にコードを書いたときに 行われるなら、伸びるのが当然のような気がします。 皆さんの処理系では、どうなるでしょうか?
371 名前:デフォルトの名無しさん mailto:sage [2005/06/16(木) 14:44:44 ] destructive か non-destructive の差だろ。 実装による。
372 名前:デフォルトの名無しさん mailto:sage [2005/06/16(木) 14:48:44 ] >>370 '(title =)のセルが作られるのはトップレベルの内部で呼ばれるread関数の中。 エディタは文字列で持っているが、それがLispの世界に渡されるときにconsセル に変換される。君の場合はC-jを押したときに起こっているはず。 あとyの値がアトムでは面白いことは起きないだろ。 (setq y '(hoge)) (defun f () (setq x (nconc '(title =) y))) しておいて(f)を評価してみ。2回目の評価で凄いことが起きるぞ。w
373 名前:デフォルトの名無しさん mailto:sage [2005/06/16(木) 14:50:01 ] >>371 nconcがdestructiveでない実装ってある?
374 名前:364 mailto:sage [2005/06/16(木) 16:39:48 ] 大変よく分かりました。ありがとうございます。というか、実に自分は分かっ てませんでした。 (setq y '(hoge); リストを入れる。 (f); 評価にあたって、バイトコンパイルの必要はない。 =>(title = hoge) ; 1回目 =>(title = hoge hoge . #2) ; 2回目 =>無限ループ ;3回目...あわてて C-g で停止。 nconc は破壊的だから、同じリストを nconc で何度も結合すると、自己参照 が起きてしまうのですね。私のところで問題が起きなかったのは、一つはアト ムを nconc していたからなのですね。 まとめると、こんな感じでしょうか。 ・(setq x (nconc '(title =) y)) の評価は、これを素で評価するのと、関数 に入れて評価するのとで、結果が違う。 ・(setq z '(title =)) として、(setq x (nconc z y)) を評価すると、素で 評価しても、関数に入れても同じ結果になる。 ・だから、Common Lisp では、quote 式のリストに破壊的操作を行ってはなら ないことになっている。
375 名前:デフォルトの名無しさん mailto:sage [2005/06/16(木) 18:54:46 ] 違う。それだと (setq x (nconc (list 'title '=) y)) でも同じだよね。 * '(a b c) のようなフォームはリテラルと呼ばれ、コンパイル時に作成される。 * だから (defun f () '(a b c)) の時、(eq (f) (f)) は真になる。 * もしここでリテラルの変更を許可してしまうと (f) => '(a b c) (nconc (f) '(d e f)) (f) => '(a b c d e f) となり、参照透過性が保てなくなる。 * また、コンパイラは同じ値のリテラルを同じオブジェクトにしてもかまわない。 (setq x '(a b c) y '(a b c)) において (eq x y) が真になってもかまわない ということ。そのような最適化をするコンパイラでは (setq x '(a b c) y (nconc '(a b c) '(d e f))) で x まで '(a b c d e f) になってしまう。
376 名前:デフォルトの名無しさん mailto:sage [2005/06/16(木) 20:06:54 ] >>375 「コンパイル時に作成される」という言い方は抵抗あるなぁ。 基本的にはインタプリタでも事情は似たようなもんだから。 同一リテラルを再利用する最適化はread関数が行う可能性も あるし、もちろんコンパイラが行う可能性もある。 (実際にやる処理系は見たことないけど)
377 名前:363 mailto:sage [2005/06/16(木) 21:16:25 ] 興味深い、ありがとうございました。 しかし、後者の理由はわかりますが、前者の参照透過性については、副作用の ある関数も多いわけですから(カウントアップのクロージャとか)、純粋な関 数型言語でない LISP にとってそれほど重要なのか、よく分からないです。 あと、 (setq y '(hoge)) (defun f () (setq x (nconc (list 'title '=) y))) これだと、(f) を何度評価しても、結果は (title = hoge) なのですが。
378 名前:363 mailto:sage [2005/06/16(木) 21:17:16 ] あ、日本語がおかしい。「興味深いお話、ありがとうございます」でした。
379 名前:375 mailto:sage [2005/06/16(木) 22:16:50 ] >>376 インタプリタであっても、クロージャの作成等ある程度の変換処理が入るので、 そういった物も含めてコンパイラと書いたんだけど、 Common Lisp では 「コンパイラ」という用語は interpreted function を compiled function に 変換する機能として定義されてるからよくなかったね。 「処理系によって作成される」等に訂正。 ところで、read 関数が返すのは #n# 等の例外を除いて新規に割り当てられる ことが保証されてなかったっけ。reader の段階では '... を (quote ...) と 変換できることは知ってても (quote (a b c)) がリテラルであり再利用可能 であることは知らないはずだけど。 もし保証されてないとすると、prin1 で保存したデータを read して破壊的操 作してるコードを修正しないと。。。 >>377 一見参照透過に見えるのにそうでないのは混乱の元だってこと。 実際にはリテラルを直接返すのは呼び出し元の挙動に依存するので あまり好ましいやり方じゃないんだけどね。 あと、後半部についてはそのとおり。(setq x (nconc (list ... はまとめ の部分に対してのコメント。
380 名前:363 mailto:sage [2005/06/16(木) 23:07:13 ] なるほど、意図を逆だと勘違いしていました。すみません。
381 名前:デフォルトの名無しさん mailto:sage [2005/06/16(木) 23:26:37 ] すみませんが質問です。 Windows で Scheme を書いておられる方は、環境に何をお使いですか?Emacs の scheme-mode + run-scheme と似たような環境がほしいのです。 ・ChezEdit ... Shift + F2 で範囲選択した個所を評価・実行できるので、Emacs と かなり使い勝手は近い。しかし Petite Chez Scheme 専用。また Windows95 系の OS では動かない。 ・xyzzy ... scheme-mode はあるが、run-scheme はない。 ・Meadow ... 使ったことないけれど、run-scheme は Gauche ではうまく動かない らしい。 ・Dr.Scheme ... MzScheme 専用。英語なので使い方がよく分からない。
382 名前:デフォルトの名無しさん mailto:sage [2005/06/17(金) 04:17:37 ] お願い: ある処理系で Shift_JIS をサポートするに当たり、locale が Shift_JIS の 際の nl_langinfo(CODESET) の値を調べてます。 以下のコードを foo.sh と保存し、sh foo.sh の結果を教えてください。 ちなみに、当方では以下のようになります。 FreeBSD 5.4-RELEASE-p2 codeset: SJIS --ここから-- foo.sh #! /bin/sh c=$0.$$.c o=$0.$$.out cat > $c <<__EOF__ #include <langinfo.h> #include <locale.h> #include <stdio.h> main() { setlocale(LC_ALL, ""); printf("codeset: %s\n", nl_langinfo(CODESET)); } __EOF__ cc -o $o $c uname -sr for l in $(locale -a | grep -i -e sjis -e 'shift.*jis'); do LC_ALL=$l ./$o done | sort -u rm $c $o --ここまで--
383 名前:デフォルトの名無しさん mailto:sage [2005/06/17(金) 05:25:49 ] SolarisではPCKだったと思うのでひっかからないような。
384 名前:デフォルトの名無しさん mailto:sage [2005/06/17(金) 05:27:28 ] スレ違いなものにレスをつけてしまったorz
385 名前:デフォルトの名無しさん mailto:sage [2005/06/17(金) 09:07:13 ] あっそ、じゃあ調査は終了。
386 名前:381 mailto:sage [2005/06/17(金) 10:42:50 ] うわーい、全然レスがついてません。まいりました。 みんなホント、Windows でどうやってるんですか?Gauche を Windows に移植 した人たちとか、一体どんな環境で Gauche を使いたくて移植したんでしょうか?
387 名前:デフォルトの名無しさん mailto:sage [2005/06/17(金) 11:18:19 ] >>381 Windows でも Emacs(Meadow) + scheme-mode + run-scheme ですが何か?
388 名前:381 mailto:sage [2005/06/17(金) 12:52:38 ] >>387 すみません、Meadow は Gauche を普通に使えるみたいですね。 64.233.161.104/search?q=cache:pD4TKAZBB8cJ:eclipse.neneko.com/diary/20040313.html Meadowのrun-schemeでGaucheを使う場合には-iオプションを付ける必要がある. (setq scheme-program-name "gosh -i") 少し質問させてください。 ・Meadow で MzScheme、Chez Scheme などは使えますか? ・もう少し軽い環境はないでしょうか?VisualStudio が軽々動くマシンでし たら、Meadow + Cygwin も問題なく使えるのだろうと思うのですが、私の Windows 機は xyzzy ももっさりしているぐらいなので。
389 名前:デフォルトの名無しさん mailto:sage [2005/06/17(金) 12:59:07 ] Windowsの代わりにLinuxかFreeBSDでも入れて、GnomeやKDEなんかの 重たいデスクトップ環境を使わないようにすれば古いPCでも快適ですよ。 当方は初代ThinkPad560をそうやって使ってます。買い替えたのは内蔵 ハードディスクだけ。GoshもMzSchemeもそこそこ快適に動きますよ。
390 名前:381 mailto:sage [2005/06/17(金) 15:15:05 ] ありがとうございます。実は、Linux をすでに別のマシンに導入しており、 Emacs21 + Gauche を快適に使っています。それまでずっと Windows (とその 系統のソフト)しか使っていなかったので、こんなに便利な環境があるなんて、 想像もしていませんでした。今まで使わないで大損をしていた、と後悔してい るほどです。 www.math.s.chiba-u.ac.jp/~matsu/emacs/emacs21/scheme.html 現用の Windows(98)機は事情があって、Linux を入れることはできないのです が、このマシンでも Petite Chez Scheme は意外に早く動くので、こちらでも もう少し環境を整えられないかな、と思ったのです。Emacs 環境がいかに便利 とは言え、長く使った Win 版ChezScheme に少々愛着もありますので。
391 名前:デフォルトの名無しさん mailto:sage [2005/06/17(金) 21:13:21 ] >381 >Windows で Scheme を書いておられる方は、環境に何をお使いですか? DrScheme 使ってる。 >Dr.Scheme ... MzScheme 専用。英語なので使い方がよく分からない。 最近 GUI が日本語化されたよ (v299.106 以降)。 マニュアルは英語のままだけど。
392 名前:デフォルトの名無しさん mailto:sage [2005/06/17(金) 21:39:49 ] >>391 それって、どこでダウンロードできますか?下記のサイトではまだ Version:299.100 なんだけど。 download.plt-scheme.org/drscheme/
393 名前:デフォルトの名無しさん mailto:sage [2005/06/17(金) 21:50:31 ] pre.plt-scheme.org/installers/table.html
394 名前:デフォルトの名無しさん mailto:sage [2005/06/17(金) 22:20:52 ] ありがとう!これはなかなか凄そうだ!
395 名前:381 mailto:sage [2005/06/17(金) 23:44:45 ] Dr.Scheme(PLT Scheme)は、Windows の COM オブジェクトの操作ができるとい うので、とても興味があります。 いくつか質問させてください。 ・開発環境は、日本語は通りますか? ・エディタ画面の、指定した範囲の評価はできますか? (Emacs の C-x C-e にあたるもの) ・エディタ画面は、S式単位の編集はできますか? (参照:4.2. カーソル移動) www.kahua.org/cgi-bin/khead.cgi/kahua-web/show/eg/emacs ・Emacs キーバインドにすることはできますか? ・以前試したとき、素のMzScheme は結構早いのに、Dr.Scheme環境だと大変遅 くなった記憶があります。今はどうでしょうか?遅いままだとしたら、使い 方による回避はできますか? たくさん聞いてすみません。私のほかにも、興味はあるけど手を出せないでい る人は多いと思いますので。少しでも答えてもらえたら、大喜びです。
396 名前:デフォルトの名無しさん mailto:sage [2005/06/17(金) 23:52:39 ] >興味はあるけど手を出せないでいる人は多いと思いますので。 この辺が漏れには理解できないんだよね。 とりあえず試してみればいいのに。
397 名前:デフォルトの名無しさん mailto:sage [2005/06/18(土) 00:08:12 ] (本音-of >>395 ) => いちいち試すの面倒だからさっさと教えろよ!
398 名前:デフォルトの名無しさん mailto:sage [2005/06/18(土) 07:13:00 ] >>395 (cond (開発環境は、日本語は通りますか? 今時Unicode対応は標準だと思うんだが.....) (エディタ画面の、指定した範囲の評価はできますか? そんなことすらできないものをIDEと呼ぶはずが無いと思うんだが....) (エディタ画面は、S式単位の編集はできますか? できなかったらキーボードに突っ伏して寝てしまうほど基本的な機能だと思うんだが....) (Emacs キーバインドにすることはできますか? キーバインド固定のIDEなんて絶滅して久しいと思うんだが....) (素のMzScheme は結構早いのに、Dr.Scheme環境だと大変遅くなった記憶があります。 デバッグ機能を外せば実行は早くなると思うんだが....) (else 予想と現実ってあんまり一致しないんだよな))
399 名前:381 mailto:sage [2005/06/18(土) 08:48:50 ] すみません、確かに少々ずうずうしい質問でした。 実は、最新版を一応インストールして、少し試してはいたのですが、知人のマ シンを借りて行っていたので、きちんと試す時間がなかったのです。だから試 したとは書かなかった(書けなかった)のですが、>>395 の質問項目は、いず れもその短い時間で解決できなかった項目を、知人のマシンから書き込んだも のです。 現在は自宅の自分のマシンですが、実は、インストールしようとすると、何度 やってもインストーラが途中で失敗してしまいました。おそらくメモリ不足で しょう。知人のマシンで試した時、かなり重かったので、うまく行かないよう な気がしてはいたのですが。 ただ、開発環境としては非常に興味があります。将来、新しいマシンを入手し た時のために、参考になることを教えてもらえたら、大変ありがたいのです。
400 名前:デフォルトの名無しさん mailto:sage [2005/06/18(土) 18:14:12 ] (atom 381) nil
401 名前:デフォルトの名無しさん [2005/06/18(土) 20:25:36 ] Scheme で (if #t (define abc 123)) とするとエラーになるのはなんで?
402 名前:デフォルトの名無しさん mailto:sage [2005/06/18(土) 20:31:44 ] >>401 そこは define の書ける場所ではなから。
403 名前:デフォルトの名無しさん [2005/06/18(土) 20:36:01 ] なぜ、書けないのでしょうか。 たとえば、何らかのフラグ (これこれのシンボルが定義されているかどうか) によって、定義を変えたいときは、どのようにするのがよいでしょうか。
404 名前:デフォルトの名無しさん mailto:sage [2005/06/18(土) 20:37:27 ] >>403 set!
405 名前:デフォルトの名無しさん mailto:sage [2005/06/18(土) 20:38:24 ] >>404 すいません、もう少し詳しく説明していただけませんか?
406 名前:デフォルトの名無しさん mailto:sage [2005/06/18(土) 20:42:17 ] >>405 (define abc 123) (if 何かの条件 (set! abc 456)) みたいにすればいい。 define は他の言語での変数の宣言に近い。 純粋な代入は set! を使う。
407 名前:デフォルトの名無しさん mailto:sage [2005/06/18(土) 20:47:23 ] > 他の言語での変数の宣言に近い。 なるほどー。 今の例だと、123 という簡単な値なのでよいのですが、 たとえば、構文の定義を変えたい場合はどうでしょう? たとえば、Windows と Mac で、構文の定義を変えたい場合です。 シンボル WIN32 が定義されていれば Windows の定義にしたい。 これも set! で可能でしょうか?
408 名前:デフォルトの名無しさん [2005/06/18(土) 20:47:26 ] >>402 ブロックの先頭だから書けるはずじゃない? ローカルスコープなので>>401 の例では無意味だが。 ちなみにGaucheだと書けるが、グローバルにabcが定義されちゃう。 これはバグだと思うが。
409 名前:デフォルトの名無しさん mailto:sage [2005/06/18(土) 20:56:48 ] >>408 R5RS的にはdefineが書けるのはトップレベルか<body>の先頭。 ifの中の式は<body>ではないのでR5RS的には駄目。 つまり、lambdaとかletなどの新しいスコープを作る場所でのみ許すという 考え方だとおもわれる。 Gaucheの場合、トップレベルのifの中はまだトップレベルのスコープだという 解釈なのではないかな。これはこれで便利に使えそうな気がする。
410 名前:デフォルトの名無しさん mailto:sage [2005/06/18(土) 20:58:01 ] おれならMLですまーとにかくけどねw
411 名前:デフォルトの名無しさん mailto:sage [2005/06/18(土) 21:00:46 ] >>407 構文というのがマクロの定義を変えたいという意味なら不可だと思う。 (Gaucheなどは>>409 で書いたように可能かもしれないが) 関数の定義を変えたいという意味であれば、 (set! func (lambda (...) ...)) のようにすれば定義を変更できる。
412 名前:デフォルトの名無しさん mailto:sage [2005/06/18(土) 21:10:01 ] >>411 > 構文というのがマクロの定義を変えたいという意味なら不可だと思う。 そうですかー。 できてもよさそうな機能なんですけど。。 > 関数の定義を変えたいという意味であれば、 > (set! func (lambda (...) ...)) > のようにすれば定義を変更できる。 Scheme コードをコンパイルする場合、 これだと無駄なコードがコンパイルされてしまいますよね。 だから、構文展開時に切り替えたいんです。。
413 名前:デフォルトの名無しさん mailto:sage [2005/06/18(土) 22:07:43 ] >>412 > これだと無駄なコードがコンパイルされてしまいますよね。 仮に if の中に define が書けたところで、この辺の事情は 変わらないと思うのだが。
414 名前:デフォルトの名無しさん mailto:sage [2005/06/18(土) 22:09:07 ] >>412 そんなのが気になるなら、win32.scm macos.scm とかにプラットフォーム 依存の構文を入れておいて、make 等でそれを target.scm にコピー、 使用する際は (load "target.scm") するようにすれば?
415 名前:デフォルトの名無しさん mailto:sage [2005/06/18(土) 22:22:48 ] 基本すら理解できていないのに、何故そんな枝葉にこだわるのか
416 名前:デフォルトの名無しさん mailto:sage [2005/06/18(土) 23:22:26 ] 俺もそうだけど、初学者ってそういうもんじゃないかな。 今の疑問が枝葉かどうか判別するには、ある程度見通しが立ってないと。
417 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 00:39:27 ] それは学習の仕方が下手なだけ。 ある程度学習経験があれば、そういうところにあまり時間を浪費せずに進み 後でわかるようになってるという進め方が普通。 その決断が自分でできないなら、疑問点をまとめてリストアップしておく ノートを作っておけばいい。ノートに覚えてもらうわけだ。 先に進んで問題にぶちあたったとき、スキップした項目が理解に関連するなら そのとき立ち戻ればいい。
418 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 00:58:21 ] まぁ、理想的にはその通りなんだろうけどね。 マンドクサ狩りの俺みたいなのは Scheme には #ifdef ないのか マンドクセ とりあえず放置... で終了する事が多いんで、疑問は感じた時に解決っつー スタンスもありだと思うよ。
419 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 00:59:43 ] 結局だれも解決できないんじゃ。。。 だから初学者だの何だのと言って話をそらすんじゃ。。
420 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 01:08:10 ] >>419 んなこたぁないょ
421 名前:ミミ mailto:sage [2005/06/19(日) 01:15:26 ] こんなんでどう? MzScheme だけど。 (define-syntax (if-for-syntax stx) (syntax-case stx () ((_ TEST-EXPR TRUE-EXPR FALSE-EXPR) (if (eval #'TEST-EXPR) #'TRUE-EXPR #'FALSE-EXPR)))) (define PLATFORM "Windows") (if-for-syntax (string=? PLATFORM "Windows") (begin (define Vendor "Microsoft") (define Color "Blue")) (begin (define Vendor "Unknown") (define Color "Red"))) (display Vendor)
422 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 01:18:41 ] >>419 そもそも、言語処理系のユーザが考えるべき問題じゃないし、 ユーザレベルで解決できる問題じゃないってこと。 マクロがどう展開されるか、関数がどう最適化されるかって問題だろ? 部分評価とかする処理系なら、>>412 みたいな心配はないかもしれない わけだし。
423 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 01:26:12 ] >>419 414 で解決したと思ってたんだけど
424 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 01:32:31 ] それもありだけど。
425 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 01:59:01 ] SRFI 0 の feature にプラットフォームも入れてくれる処理系なら (cond-expand (win32 ...) ((or unix macosx) ...) (else ...)) とか
426 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 18:16:57 ] 前も書いた気がするが、おれの処理系は#if #else #endif をreadに入れたよ。 >>425 みたいに無駄にS式縛りにするのは面倒だし 読みにくいと思ってる。 S式に縛られてないから任意の箇所で (func #if (defined 'platform-win32) 1 2 3) #else #if #t 4 5 6) #else 7 8 9) #endif #endif みたいなことができる。 まあSRFIレベルの定義じゃ無理だな。
427 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 18:42:54 ] >>426 エディタはちゃんとインデントしてくれるの?
428 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 18:44:20 ] ちなみにCommon Lispだと#+, #-でやるよね. CL風の#+ #-が使えるScheme処理系ってないの?
429 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 19:00:36 ] プラットフォームで分けたい場合って、関数の中身の処理だけ違っていてインターフェースは同一なはずだから scheme だと単純に変数へ束縛する関数オブジェクトを変えればいいだけになる。 だから scheme ではわざわざ新しい構文を導入するまでもなく (define hoge (if (eq? 'platform win32) (lambda (arg) ...) (lambda (arg) ...))) とかすればいい。 そしてなにより美しい。 ← 一番重要w
430 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 19:07:30 ] 実行時に (if (eq? ... したくないって流れだと オモテタ けど...
431 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 19:11:00 ] >>430 マクロ展開されるのだって1回だけと期待できるにせよ実行時だし、 >>429 のifだってよほどnaiveな実装でない限り、1回しか実行されない。 わかってる?
432 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 19:25:25 ] >>431 コンパイルが別パスの処理系ならマクロ展開はコンパイル時が普通じゃない? そしたら実行イメージに余分なコードは入らない.
433 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 19:27:49 ] >>432 別パスなコンパイラ使うなら、それこそ適当なプリプロセッサでも使えば 良いじゃん
434 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 19:28:48 ] >>431 あらかじめコンパイルしたファイルをダンプしておいた場合も if は評価されない?
435 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 20:10:04 ] >>434 あらかじめコンパイルしたファイルをダンプするって意味が良くわからないが、 >>429 の例を借りると、hogeの束縛時つまり(define hoge ...)の実行時に1回if は評価されるし、されないと困る。が、これによって定義されたhogeを評価 する時には(if (eq? 'platform win32) ...)部分のifを評価するような処理系は 存在しない。
436 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 21:18:53 ] ごめん・・・俺の作った処理系・・・評価しちゃう・・・
437 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 22:07:44 ] >>429 言いたいことはわかるが、別に美しくない。 使う側はそんな事のためにlambdaに分離してまでやりたくないんだよ。 使う側の気持ちを素直に酌めば、S式縛りでやるなら (if (eq? 'platform win32) (define (arg)...) (define (arg)...)) と書いた方が自然なのでは。 おれの処理系では書けるし、実装するためのトリックみたいなものもない。 逆にscheme的には書けないのはおかしい気がする。 マクロで(begin (define 〜)(define 〜))と書きたい場合もあるし。 まあ、#if〜#endifを作るまではおれもこういう方法を仕方なくとってたけど、 条件毎に余計な部分まで定義をまるごと書かないとダメな点が どうにも我慢ならなくて切捨てた。
438 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 22:13:37 ] >>437 おまいの処理系自慢はいいよ。Schemeの話してるんだから。
439 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 22:28:16 ] 悪かったよ。 おれも散々悩んだ部分だし。 schemeの中だけでやるなら429みたいな方法しかない。 あとは処理系依存だろ。
440 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 22:34:13 ] つか、こういう時のための SRFI-0 だろ
441 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 22:37:55 ] R5RS見るとトップレベルのbeginだけ例外になってるのな。 萎え。
442 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 22:39:37 ] SRFIのせいでどんどんschemeが変な言語になって行くと思うのは俺だけですか。
443 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 22:44:54 ] >>442 でも無いといろいろと再発明する羽目になるからなぁ。 きれいで使えないよりは変で使えるほうがいい。
444 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 22:47:00 ] SRFIとR6RSの関係ってどうなるの?
445 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 23:20:01 ] >>436 評価するとなると、ifの中に副作用の有る式が書かれていたらプログラムの意味が変わるでしょ。それじゃ全然Schemeじゃないじゃん。 それとも、副作用がないということがプログラム解析で証明できたときだけ評価するの?
446 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 23:30:07 ] 「処理系が存在しない」 「naiveな実装でない限り、1回しか実行されない」 「それじゃ全然Schemeじゃない」 どれが正しいのか教えてください。
447 名前:デフォルトの名無しさん mailto:sage [2005/06/19(日) 23:44:06 ] Scheme ってリーダーマクロ使わないの?
448 名前:デフォルトの名無しさん mailto:sage [2005/06/20(月) 00:05:30 ] 今はSchemeの話をしてるのだから、 上の「処理系が存在しない」と俺の処理系は評価するが?に対する 「それじゃ全然Schemeじゃない」ってのは同じことじゃね?
449 名前:3才児 mailto:sage [2005/06/20(月) 00:23:04 ] チンカスの匂いがしてきまちた
450 名前:デフォルトの名無しさん mailto:sage [2005/06/20(月) 00:41:53 ] >>444 SRFI でも obsolete 扱いのやつはあるんじゃなかったっけ? 順次、事実上の格下げされていくんじゃないかな。R6RS と コンフリクトしそうな物とかも。 R6RS が出来ても、実装が普及するまで時間が掛かるだろうから、 しばらくはそのままなんだろうけど。
451 名前:デフォルトの名無しさん mailto:sage [2005/06/20(月) 07:29:45 ] car cdr atom eq cons は、LISP の5つの基本関数である。それ以外の関数は、 全てこれらを使って合成できるとされる。数学で言う公理に当たる。 car 板 hobby7.2ch.net/car/ cdr 板 pc8.2ch.net/cdr/ atom 板 society3.2ch.net/atom/ eq 板 live18.2ch.net/eq/ cons 板はまだない。速やかな板新設が必要ではないだろうか。
452 名前:デフォルトの名無しさん mailto:sage [2005/06/20(月) 07:31:29 ] WindowsXP 上で CLISP を実行すると WARNING: locale: no encoding CP932, using UTF-8 WARNING: *TERMINAL-ENCODING*: no encoding CP932, using UTF-8 WARNING: *FOREIGN-ENCODING*: reset to ASCII といった具合に文字コード関連の警告が出ますが これを解決する方法をご存知でしたらご教示ください。
453 名前:デフォルトの名無しさん mailto:sage [2005/06/20(月) 07:49:45 ] >>400 今意味が分かったw >>381 には悪いがちょっと ワラタ
454 名前:デフォルトの名無しさん mailto:sage [2005/06/20(月) 09:16:09 ] (if (eq? platform 'win32) (define hoge ...) (define hoge ...)) とかが許されないのは、プログラム全体をCやネイティブに変換するコンパイラーとかで面倒だからでないかい? 例えば、同じコンパイルユニットの中でplatformが定義されていれば、コンパイラーはどっちのdefineをコンパイルして書き出すか判断できるけど、 platformが独立にコンパイルされる別のユニット内で定義されている場合には、特別な仕組みが必要に思える。 そういった足枷をつけるより、ライブラリーレベル(srfi-0)で対応した方が良いということで現行のようになったんだと思ってるんだけど。 どう思う?
455 名前:デフォルトの名無しさん mailto:sage [2005/06/20(月) 20:57:56 ] >>454 すまんが言ってることがわからん。 >platformが独立にコンパイルされる別のユニット内で定義されている場合 この辺をもう少し説明してほしい。 platformが未定義の場合ということ? 定数畳み込みで消えずに未定義でコンパイル通ったとしても、 一度はどっかで実行されるわけだから 最悪ランタイムエラーになったり、 コンパイルの段階で未定義エラーで検出するで良いんじゃないの? さっぱりわからん。 >特別な仕組み 特別な仕組みとは? >ライブラリーレベル(srfi-0) cond-expandという名前が気に食わん。 適当としか思えない・・
456 名前:デフォルトの名無しさん mailto:sage [2005/06/20(月) 21:10:30 ] 未定義エラーはリンクの段階かもしれん。
457 名前:デフォルトの名無しさん mailto:sage [2005/06/20(月) 23:35:56 ] >>443 CL使っとけ。
458 名前:デフォルトの名無しさん mailto:sage [2005/06/21(火) 01:27:02 ] cmucl とかアセンブラ(に変換するlisp)で書かれているし。
459 名前:デフォルトの名無しさん mailto:sage [2005/06/21(火) 01:35:40 ] >>457 再発明なんて高々一回程度だよ。 古臭いCL使うぐらいなら再発明も悪くないだろう。
460 名前:デフォルトの名無しさん mailto:sage [2005/06/21(火) 02:49:08 ] CommonLispもSchemeもそうやって作られてきた。
461 名前:デフォルトの名無しさん mailto:sage [2005/06/21(火) 06:49:58 ] >>452 コマンドラインで、clisp -E ASCII とかどう?
462 名前:デフォルトの名無しさん mailto:sage [2005/06/22(水) 16:59:02 ] schemeを始めたんですけどリストを逆順にする関数がわかりません。 (define (reverse lst) (if (null? lst) '() (cons (reverse (cdr lst)) (car lst)))) こうやるとペアになってしまいます。 (reverse '(1 2 3)) ((3 2) . 1) (3 2 1)となるやつをおしえてください。
463 名前:デフォルトの名無しさん mailto:sage [2005/06/22(水) 17:29:15 ] (define (reverse lst) (if (null? lst) '() (append (reverse (cdr lst)) (cons (car lst) '()))))
464 名前:デフォルトの名無しさん mailto:sage [2005/06/22(水) 17:42:55 ] >>462 ↓わかりやすい例 (define (my-reverse lst) (if (null? lst) '() (append (my-reverse (cdr lst)) (list (car lst))))) ↓より効率の良い例 (define (my2-reverse lst) (my2-reverse-1 lst '())) (define (my2-reverse-1 lst done) (if (null? lst) done (my2-reverse-1 (cdr lst) (cons (car lst) done))))
465 名前:デフォルトの名無しさん mailto:sage [2005/06/22(水) 17:48:54 ] >>463 そりゃ効率が悪いよ。append で同じリストを何回もコピーしてしまう。 こっちの方がいいと思う。 (define (my-reverse list0) (let loop ((list0 list0) (result '())) (if (null? list0) result (loop (cdr list0) (cons (car list0) result)))))
466 名前:465 mailto:sage [2005/06/22(水) 17:50:23 ] あ、やっぱりかぶっちゃった。 私のはローカル関数を使って一つにまとめたバージョンということで。
467 名前:デフォルトの名無しさん [2005/06/22(水) 18:41:55 ] こういう片方向のリスト演算って、 他の言語だとしょーもないライブラリ関数や自作関数で 限定的にやるしかないんだよね。 やっぱ年季が違うなあ。 LISPすごい。