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 あたり
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すごい。
468 名前:デフォルトの名無しさん mailto:sage [2005/06/22(水) 19:39:23 ] (define my-reverse reverse)
469 名前:デフォルトの名無しさん mailto:sage [2005/06/22(水) 19:54:52 ] ワラタ。 (setf (symbol-function 'my-reverse) #'reverse)
470 名前:デフォルトの名無しさん mailto:sage [2005/06/22(水) 20:01:19 ] 無知丸出しw
471 名前:デフォルトの名無しさん mailto:sage [2005/06/22(水) 20:04:33 ] えー、どうやるの?
472 名前:デフォルトの名無しさん mailto:sage [2005/06/22(水) 20:07:53 ] >>470-471 え、なんかあったの?
473 名前:デフォルトの名無しさん mailto:sage [2005/06/22(水) 20:17:37 ] 無知ですいません。 これって Common Lisp だとどう書くのがスマートなんでしょうか?
474 名前:462 mailto:sage [2005/06/22(水) 21:09:29 ] 理解できました。ありがとう。
475 名前:デフォルトの名無しさん mailto:sage [2005/06/23(木) 06:31:50 ] (define (my-reverse! list0) (let loop ((list0 list0) (result0 '())) (if (null? list0) result0 (let ((result1 (loop (cdr list0) list0))) (set-cdr! list0 result0) result1))))
476 名前:デフォルトの名無しさん mailto:sage [2005/06/23(木) 06:49:08 ] !イラネ!!
477 名前:デフォルトの名無しさん mailto:sage [2005/06/23(木) 07:32:30 ] 効率命の破壊的リスト操作なのに、スタックを消費するのがつらいところだのう。
478 名前:デフォルトの名無しさん mailto:sage [2005/06/23(木) 08:15:37 ] (define (my-reverse! lst) (let loop ((l lst) (r '())) (if (null? l) r (let ((l1 (cdr l))) (set-cdr! l r) (loop l1 l)))))
479 名前:デフォルトの名無しさん mailto:sage [2005/06/23(木) 19:25:49 ] (define my-reverse! reverse!)
480 名前:デフォルトの名無しさん mailto:sage [2005/06/25(土) 06:39:47 ] >>165 に書かれてるイベント行った方います?
481 名前:デフォルトの名無しさん mailto:sage [2005/06/27(月) 04:36:05 ] この板にちょくちょく出没している様子のtabesugiのひとが行ったんじゃないか?
482 名前:デフォルトの名無しさん mailto:sage [2005/06/27(月) 22:50:00 ] Scheme のレキシカルスコープは Algol 60 の影響なのでしょうか? 私はラムダ計算の変数の、自由変数と束縛変数による影響だと思った のですが。
483 名前:デフォルトの名無しさん mailto:sage [2005/06/27(月) 22:58:18 ] 1970年代のLispは動的スコープが主流でFUNARG問題に悩んでいた。 それに対するアンチテーゼというか実験としてSchemeという言語が作ら れたような節はあるね。その後Common Lispにも採用されてLisp界全体 でもレキシカルスコープが主流になるわけだが。
484 名前:482 mailto:sage [2005/06/27(月) 23:10:36 ] >>483 もっと計算機よりの実装を知らなければならなかったのですね。 Lisp の歴史を勉強してみてよくわかりました。m(_ _)m
485 名前:デフォルトの名無しさん mailto:sage [2005/06/28(火) 08:54:21 ] Emacsが動的スコープなんで、何でレキシカルスコープじゃないの?とRMSに 尋ねた人によると、「レキシカルスコープは実行速度が遅い」といったそうな。 昔の話。
486 名前:デフォルトの名無しさん [2005/06/28(火) 09:22:24 ] International Lisp Conferenceに参加した人に聞いたんだけど、結構を盛り上がってたって聞いた。 結構人も集まってて、熱心な若者Lisperも結構いたのに驚いたとか。 bioinformatics系のアプリが結構多くて、時代の流れを感じたとか。 当日proceedingsが配布されたけど、後日、 www.international-lisp-conference.org から販売するそうな。
487 名前:デフォルトの名無しさん [2005/06/28(火) 12:56:20 ] 理解に苦しんでいるstatic scopeの話がちょうど出たようですので、 質問させてください。 ;;; 例-A ---------------------------------------- A1> (define foo begin) A2> (define bar (lambda (a b c) (foo a b c))) A3> (bar #t 0 1) ;;==> 1 A4> (define foo list) A5> (bar #t 0 1) ;;==> 1 ;;; 例-B ---------------------------------------- B1> (define foo (lambda (m) (- m 3))) B2> (define bar (lambda (n) (foo n))) B3> (bar 10) ;;==> 7 B4> (define foo (lambda (m) (+ m 3))) B5> (bar 10) ;;==> 13 例-Aのほうは、fooをtop-levelで再定義(A4)しても、 barを呼び出したとき(A5)には、手続き定義時(A2)の 環境が使われています。 これはstatic scopeの考え方からすると当然だと 思えるようになりました。 ところが、例-Bのほうは、 fooを再定義(B4)すると、手続き呼び出し時(B5)には 手続き定義時(B2)のfooではなく、再定義されたfooが 使われています。 この違いは何でしょうか?
488 名前:487 [2005/06/28(火) 13:00:37 ] 失礼。 static scopeではなくて、lexical scopeでした。
489 名前:デフォルトの名無しさん mailto:sage [2005/06/28(火) 13:20:54 ] >>487 変数が既に束縛されている場合の top level での define は set! と同等な ので例-B が妥当。例-A は A1 で変数に syntax を代入してるけど、変数経由 で syntax を使用した場合の動作は未定義のはず。たぶんその処理系では foo も syntactic keyword になって、かつ A2 の段階で展開されてしまってるん じゃないかと思う。
490 名前:487 [2005/06/28(火) 13:52:58 ] >>489 ありがとうございます。 > 変数経由で syntax を使用した場合の動作は未定義のはず。 これって、どこかに書いてありますか? 書いてないから未定義なのかな? ここらへんのことをよく知りたいと思っているのですが、よい 資料はありますでしょうか?
491 名前:デフォルトの名無しさん mailto:sage [2005/06/28(火) 17:17:51 ] >>490 >これって、どこかに書いてありますか? >書いてないから未定義なのかな? おれは489ではないのだがちょっと失礼する R5RSの5.2 Definitionsによれば、定義は (define <variable> <expression>) でもって7.1.3. Expressionsにはsyntactic keywordが<expression>になる記述は無い。 だから、(define foo begin)はR5RS的には有効ではないと思われる(例えばPLTとかchezとかはシンタックスエラーとなる) しかし1.3.2 Error situations and unspecified behaviorによれば処理系にそのエラーの報告義務は無い。 つまり動作は未定義で処理系依存でよいということであり、(define foo begin)などが通る場合は処理系独自の拡張の結果という事だと考えて良いと思うんだけど.......これでいいのかな?皆の衆
492 名前:487 [2005/06/28(火) 20:17:38 ] >>491 なるほどR5RSはそういう読み方をしなければいけないんですね。 私が試した処理系のほとんど(kawa,guile,gosh)では >>487 例-Aのようになったので、そうあるべきなのかと思いこんでいました。 唯一biglooと個人的に使っているマイナーな処理系では 同様のコードを読ませると、手続き定義後の変更も反映されて A3>==> 1 A5>==> (#t 0 1) となります。 厳密にはエラーなんですね。 489さん、491さん、ありがとうございました。
493 名前:デフォルトの名無しさん mailto:sage [2005/06/30(木) 05:47:08 ] かっちょえー lemonodor.com/archives/001177.html
494 名前:デフォルトの名無しさん mailto:sage [2005/07/02(土) 08:50:26 ] >>486 日本人もたくさん参加してたのかな?
495 名前:デフォルトの名無しさん mailto:sage [2005/07/03(日) 21:51:02 ] すいません 入れ子のリストの中身を調べて 最も大きい値を返す関数の定義という問題なのですが、 例えば(al-max'((1 3)((9)4)))を与えた時9を返すような 定義を教えて頂きたいのですが。 どのようにすれば良いのでしょうか? 入れ子を考えなければ (defun max1(x)(cond((null (cdr x))(car x))((<= (max1(cdr x))(car x))(car x))(t(max1(cdr x))))) このようになるんですけど。入れ子だと良く分かりません。
496 名前:デフォルトの名無しさん mailto:sage [2005/07/03(日) 22:13:31 ] >>495 scheme だけど。 ttp://www.geocities.co.jp/SiliconValley-PaloAlto/7043/index.html#lambda fold-tree っぽいものは標準であってもいいような気がするんだけどなあ。
497 名前:495 mailto:sage [2005/07/03(日) 22:32:44 ] >>496 ありがとうございます。 サイト見ましたが高級関数を定義とか ユーティリティ関数とかさっぱり分かりません。 具体的にはどうすればいいですかね?
498 名前:デフォルトの名無しさん mailto:sage [2005/07/03(日) 22:45:38 ] (defun al-max (lst) (cond ((numberp lst) lst) ((null (cdr lst)) (al-max (car lst))) (t (max (al-max (car lst)) (al-max (cdr lst))))))
499 名前:495 mailto:sage [2005/07/03(日) 22:48:47 ] >>498 ありがとうございます! 感謝です。
500 名前:デフォルトの名無しさん mailto:sage [2005/07/03(日) 23:01:11 ] (defun al-max (x) (if (listp x) (apply #'max (mapcar #'al-max x)) x))
501 名前:495 mailto:sage [2005/07/03(日) 23:05:49 ] すいませんmax使わないで作ることって事出来ますかね?
502 名前:デフォルトの名無しさん mailto:sage [2005/07/03(日) 23:08:35 ] max
503 名前:デフォルトの名無しさん mailto:sage [2005/07/03(日) 23:09:26 ] max を使いたくないなら、自分で max を書けばいいじゃない。