[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 2chのread.cgiへ]
Update time : 05/09 15:00 / Filesize : 210 KB / Number-of Response : 784
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

Lisp Scheme Part19



1 名前:デフォルトの名無しさん mailto:sage [2008/01/14(月) 00:14:56 ]
過去スレ
Part18: ttp://pc11.2ch.net/test/read.cgi/tech/1186922295/
Part17: ttp://pc11.2ch.net/test/read.cgi/tech/1177065699/
Part16: ttp://pc11.2ch.net/test/read.cgi/tech/1172404795/
Part15: ttp://pc10.2ch.net/test/read.cgi/tech/1151025773/
Part14: ttp://pc8.2ch.net/test/read.cgi/tech/1132275726/
Part13: ttp://pc8.2ch.net/test/read.cgi/tech/1115901841/
Part12: ttp://pc8.2ch.net/test/read.cgi/tech/1100229366/
Part11: ttp://pc5.2ch.net/test/read.cgi/tech/1091456033/
Part10: ttp://pc5.2ch.net/test/read.cgi/tech/1075630259/
Part9: ttp://pc2.2ch.net/test/read.cgi/tech/1069594582/
Part8: ttp://pc5.2ch.net/tech/kako/1058/10582/1058263391.html
Part7: ttp://pc5.2ch.net/tech/kako/1042/10421/1042167213.html
Part6: ttp://pc3.2ch.net/tech/kako/1031/10315/1031560687.html
Part5: ttp://pc3.2ch.net/tech/kako/1023/10230/1023091882.html
Part4: ttp://pc.2ch.net/tech/kako/1016/10162/1016211619.html
Part3: ttp://pc.2ch.net/tech/kako/1008/10082/1008220265.html
Part2: ttp://pc.2ch.net/tech/kako/1002/10025/1002584344.html
Part1: ttp://piza2.2ch.net/tech/kako/987/987169286.html

560 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 23:27:19 ]
>>559
Drは使ったことがないのでよくわからないけど
MrEDと連携してグラフィクスなんかできたんじゃ
なかったっけ。

561 名前:デフォルトの名無しさん [2008/02/12(火) 19:14:40 ]
HaskellにはLispのような優秀なマクロがないので埋め込み言語を実装しにくいって本当かね?

562 名前:デフォルトの名無しさん mailto:sage [2008/02/12(火) 19:45:30 ]
マクロよりS式の方が大きいでしょ。
S式はDSLのプロトタイプに最適だもん。
Lisp1.5の時代から、俺eval、俺apply作れたんだから。

563 名前:デフォルトの名無しさん mailto:sage [2008/02/12(火) 19:47:36 ]
一方、しっかりした仕様のある言語なら、
pugsの例を見るまでもなくHaskellも結構いける。
宣言型のコード書きやすいから。
Prologはどっか行っちゃった。

564 名前:デフォルトの名無しさん mailto:sage [2008/02/14(木) 08:57:01 ]
第2回gauche.nightチケット売り切れました。
本当にありがとうございました。

565 名前:デフォルトの名無しさん mailto:sage [2008/02/14(木) 12:31:55 ]
どういたしまして

566 名前:デフォルトの名無しさん mailto:sage [2008/02/15(金) 00:50:36 ]
>>564
本も売り切れるといいね。

567 名前:デフォルトの名無しさん mailto:sage [2008/02/15(金) 01:05:33 ]
初心者です.マクロについて質問させてください.
以前に出ていた日本語のScheme本から(一部抜粋)
(define-syntax Cond (syntax-rules (else =>)
;; #0
((Cond (else result1 result2 ...)) (begin result1 result2 ...))
;; #1
((Cond (test => result)) (let ((temp test)) (if temp (result temp))))
;; #2
((Cond (test => result) clause1 clause2 ...)
(let ((temp test)) (if temp (result temp) (Cond clause1 clause2 ...))))
;; #3
((Cond (test)) test)
;; #4
((Cond (test) clause1 clause2 ...) (or test (Cond clause1 clause2 ...)))
;; #5
((Cond (test result1 result2 ...)) (if test (begin result1 result2 ...)))
;; #6
((Cond (test result1 result2 ...) clause1 clause2 ...)
(if test (begin result1 result2 ...) (Cond clause1 clause2 ...)))))
(let ((=> #f)) (Cond (#t => 'ok)))
scmだと本の解説通り ok と表示されるのですが, scm ではないある処理系に
読み込ませたところ,'ok がprocedureではない,というエラーになりました.
どうやら「=>」に#fが束縛されておらず keywordである「=>」として扱われたようです.
正しくは,すべてのsymbolの束縛関係が解決されてから syntaxに渡され
(て,最終的にokとな)ると考えて良いのでしょうか.

568 名前:567 mailto:sage [2008/02/15(金) 01:32:22 ]
もしそうだとすると,その束縛関係が参照されるのは,
syntax定義の時点でしょうか,それとも
syntax呼び出しの時点でしょうか.



569 名前:567 mailto:sage [2008/02/15(金) 01:57:21 ]
>>568 の質問の形を変えます.
syntax定義時と呼び出し時とで異なる値に束縛されたsymbolは
どちらの値に置き換えられて評価されるのでしょうか.
単純なscopeの優先度からすると,syntax呼び出し時の値が使われそうですが,
closureやsyntaxが制作者の意図通り動くことを保証するためには
syntax定義時の値が使われるべきなのではないかと思うのです.
closureだとclosure定義時の環境が参照されると理解しています.

570 名前:デフォルトの名無しさん mailto:sage [2008/02/15(金) 02:48:34 ]
そこまで確信してるなら「scm ではないある処理系」の製作者に直接言えば?

571 名前:デフォルトの名無しさん mailto:sage [2008/02/15(金) 08:29:51 ]
どちらが正しいかを決めるルールが存在するとは限らない。

572 名前:567 mailto:sage [2008/02/15(金) 08:52:11 ]
混乱していましたが一晩寝たら少し整理できたように思います.
本の説明とscmの実装が正しいとして,束縛関係の優先順位が
1.syntax定義時
2.syntax呼び出し時
であれば納得できそうです.

573 名前:デフォルトの名無しさん mailto:sage [2008/02/15(金) 12:51:51 ]
R5RSに於いては
マクロに於けるリテラル識別子(この場合はelseと=>)がマッチするのは
マクロ定義とマクロ使用でともに同じ束縛を持つか
ともに束縛を持たない場合のみだから
その「scm ではないある処理系」の挙動は正しくない。
マクロのパターンマッチに束縛情報が使われることから
束縛関係を解決してから展開されるという解釈は正しいと思う。
ただしSchemeの場合は値ではなく場所に束縛される。
だから
(define foo 100)
(let ((foo foo)) foo)
ではトップレベルのfooとlet式中のfooは同じ値で違う束縛である。
(さらに細かく言えば束縛されるのはSymbolではなくidentifierである。)
このCondの例は定義時に=>が束縛を持たなかったのに(あるいは定義時の字句的束縛を持っていたのに)
使用時に=>がローカルな束縛を持っていたから#1にマッチしなかっただけである。
同じ束縛を持っていた場合は変数参照式として値が使われることはなく、リテラル識別子として#1にマッチする。
また、マクロ使用において束縛関係の優先順位が
1. 定義時
2. 使用時
というのは逆。
マクロ使用式の識別子の束縛は使用される式の位置に於ける字句的束縛である。
だからマクロ名である構文キーワード(この場合はCond)はローカル変数束縛に隠蔽されうる。
ただし展開され、挿入された式は定義に於ける字句的束縛を持つ。

犬飼大氏はscmやSLIBはR5RSに準拠してると仰ってるけれども
scmや派生処理系のGNU guileはマクロ周りを含め準拠していない部分も結構あるから
R5RSの学習には不向きだと思われる。

574 名前:567 mailto:sage [2008/02/15(金) 13:04:47 ]
>>573
要を得ない質問の意図をくみ取ってくださり
的確なご解説をいただきましてありがとうございます.
>>573を読み返して考えてみます.

575 名前:デフォルトの名無しさん mailto:sage [2008/02/15(金) 14:10:32 ]
C言語風に言い換えれば束縛という名詞は変数のアドレス。

(define x 100)
(define y 1000)
(define-syntax foo (syntax-rules () ((foo y) (+ x y))))
;パターン(foo y)に現れていなくてテンプレート(+ x y)に現れている識別子は+とx
;さらに自由識別子だから
;+とxは挿入された場所の字句的束縛ではなく
;マクロ定義された場所の字句的束縛を持つ
;yはマクロに於ける仮引数だからマクロ使用の式の値になる

(let ((x 10))
 (foo y))
-> 1100
(let ((x 10))
 (foo x))
-> 110
(let ((y 1))
 (foo x))
-> 200
(let ((y 1))
 (foo y))
-> 101
(let ((+ -))
(foo 10000))
-> 10100

576 名前:デフォルトの名無しさん mailto:sage [2008/02/15(金) 14:10:53 ]
R5RS保健的マクロの束縛識別子は処理系によって解釈が分かれてるから使わない方が吉かも。
束縛識別子とは(let ((x 10)) ...)とか(define x 100)に於けるxのことで
変数捕獲を防ぐ為にリネームされるハズなんだけど
リネームしてくれないscm系
必要最小限にリネームするGauche系
必ずリネームするScheme48系があって
それぞれ挙動が違う。

577 名前:567 mailto:sage [2008/02/15(金) 14:16:58 ]
>>573
ありがとうございます.ようやく理解できました.
マクロ使用における束縛関係の優先順位も,使用時の束縛関係が
定義時の束縛関係に優先するとしたほうが自然であると納得できました.
私の混乱の原因のひとつに,マクロのtemplate上のsymbol「=>」と,
マクロを適用するユーザコード上のsymbol「=>」とを混同していたことが
ありました.これらを明確に区別すべきでした.
なお,>>567に書きました非scmの処理系はbigloo(ver.3.0c)です.
また,guileはdefine-syntaxやsyntax-rules自体を実装していないようです.

578 名前:デフォルトの名無しさん mailto:sage [2008/02/15(金) 14:18:31 ]
guileは(use-syntax (ice-9 syncase))をすると
syntax-caseとsyntax-rulesが使えるようになります



579 名前:デフォルトの名無しさん mailto:sage [2008/02/15(金) 14:22:37 ]
束縛識別子でもlet系の場合はどの処理系もリネームしてくれるんだった。
defineは使わない方が吉、の間違い。

scm系はリネームせずにdefineします。

Gaucheは(多分)set!として働く場合はリネームしませんがそれ以外はリネームします。

Scheme48系は常にリネームします。
なのでマクロテンプレート以外から参照できません。

580 名前:デフォルトの名無しさん mailto:sage [2008/02/15(金) 14:28:19 ]
ああさらに間違い。
Gaucheはトップレベルdefineはリネームせず、内部defineのみリネームするようです。

581 名前:デフォルトの名無しさん mailto:sage [2008/02/15(金) 14:36:22 ]
また少しだけ衛生的マクロが嫌いになりました

582 名前:567 mailto:sage [2008/02/15(金) 14:36:34 ]
>>575 - >>580
みなさま情報ありがとうございます
>>578 の方法でguileでも>>567のコードを正しく評価できました

583 名前:デフォルトの名無しさん mailto:sage [2008/02/15(金) 14:38:29 ]
>>577
マクロテンプレート(例えば(let ((temp test)) (if temp (result temp))))中の(この例では現れていませんが)=>は
マクロ定義された場所で可視だった束縛を参照します。

マクロパターン(例えば(Cond (test => result)))中の=>は
マクロ使用式(Cond (#t => 'ok))中の識別子=>とのマッチングに使われます。
マクロ使用式の=>とマクロ定義の=>がともに未束縛であるか
或いは同じ束縛(例えばトップレベル変数)を持つ場合にのみマッチする訳です。

584 名前:デフォルトの名無しさん mailto:sage [2008/02/15(金) 14:59:43 ]
テンプレート(foo X Y)に於いてfooという識別子に意味はありません。
最初の識別子はマッチングに利用されません。
なので(_ X Y)等と書くこともあります。

XとYはいわばメタ仮引数。マクロ使用式の同じ位置の式にマッチします。
そしてテンプレート中ではマクロ使用式の同じ位置の式が挿入されます。

(syntax-rules (hoge funi) ...)に於いてhogeとfuniはリテラル識別子となります。
パターンに現れる場合はマッチングにのみ利用されます。
マッチングは同じ識別子で且つ同じ束縛である場合にのみ成功します。

テンプレート中に現れる識別子のうち、パターンの中にリテラル識別子以外で現れた識別子以外は
マクロ定義された場所で可視だった束縛を参照します。
ただし束縛コンストラクタで作られる場所に束縛される場合は実質的に改名されます。

なのでテンプレート中に=>が出現してたらそれはマクロ定義された場所の束縛を参照します。

(define bar 100)
(define-syntax foo (syntax-rules (bar)
 ((foo bar) bar))
(foo bar)
-> 100
(let ((bar 10000))
 (foo bar))
=> ERROR! ;パターンマッチングに失敗

585 名前:デフォルトの名無しさん mailto:sage [2008/02/15(金) 15:00:33 ]
最初の単語から間違えたorz
パターン(foo X Y)の間違い

586 名前:デフォルトの名無しさん mailto:sage [2008/02/15(金) 15:36:36 ]
リテラル識別子ってsyntax-rulesのところで束縛されているように見えるけど
本当に束縛してしまうと絶対にマッチしないパターンになるのか
紛らわしいな

587 名前:デフォルトの名無しさん mailto:sage [2008/02/15(金) 15:54:38 ]
なんか長々と分かりにくい書き方だったな
リテラル識別子はパターン部分で特別扱いするだけ
でもリテラルといいながら変数と看做したときの束縛までマッチングに利用するのは少し変な気がする。

パターン変数:任意の式にマッチする。テンプレート中ではマッチした式として挿入される。
リテラル識別子:同じ束縛を持つ同じ識別子とだけマッチする。テンプレート中ではパターン変数以外の識別子と同じ扱い。
パターン変数以外の識別子:テンプレート中の変数参照はマクロ定義された位置での束縛の参照が挿入される。
 テンプレート中の束縛コンストラクタで新たに束縛される場合はその参照と共に改名される。

これの方がいいかな

588 名前:デフォルトの名無しさん mailto:sage [2008/02/15(金) 16:01:42 ]
ttp://www.r6rs.org/final/html/r6rs/r6rs-Z-H-14.html#node_sec_11.19

>A literal identifier matches an input subform if and only if
>the input subform is an identifier and
>either both its occurrence in the input expression and
>its occurrence in the list of literals have the same lexical binding, or
>the two identifiers have the same name and both have no lexical binding.



589 名前:デフォルトの名無しさん mailto:sage [2008/02/15(金) 16:55:31 ]
R5RSの3.1によれば
構文の型の名前は全て構文に束縛されていて構文キーワードである
変数とは構文キーワードでない任意の識別子である(elseと=>も構文キーワードだから変数でない)
またR5RSの4・5章によれば
defineは
(define <変数> <式>)
(define (<変数> <仮引数部>) <本体>)
(define (<変数> . <仮引数>) <本体>)
のいずれか
set!は
(set! <変数> <式>)
lambdaは
(lambda <仮引数部> <本体>) 但し<仮引数部>は(<変数1> ...)、<変数>、(<変数1> ... <変数n> . <変数n+1>)のいずれか
てことは構文キーワードをを隠蔽するローカル変数あるいはトップレベル変数をdefine、set!、lambda、let、let*、letrec、doで作る事はR5RS外だったんだ
構文キーワードの変数参照がR5RS外って事は知ってたけどこの事は知らなかった

だけど4.3にはローカル変数束縛がキーワード束縛を隠蔽しても良いって書いてあるけど
どうすれば構文キーワードを隠蔽できるローカル変数束縛ができるの?
他方、構文束縛は変数でなく識別子に対して行われるからローカル構文束縛で隠蔽されることはあり得る。

7.2.1の抽象構文に於いては変数と識別子が同一されているから<変数>の解釈が2パターンあるってオチなんだろうけど

590 名前:デフォルトの名無しさん mailto:sage [2008/02/15(金) 16:56:06 ]
typo
同一されている->同一視されている

591 名前:デフォルトの名無しさん mailto:sage [2008/02/15(金) 18:14:38 ]
Gauche0.8.13がリリースされてたのか!
気付かなかった

592 名前:デフォルトの名無しさん mailto:sage [2008/02/15(金) 18:15:03 ]
Schemeのconsを少し勉強していたら以前さっぱりだったC++の
再帰のメタプログラムがわかるようになってきた。
両方勉強しようと思う。

593 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 01:49:25 ]
すみませんが、質問です。

DrSchemeのGUI環境で、選択できる言語の一つに、遅延評価のLazy Schemeとい
うのがあるのですが、これで tarai を回して, time関数で時間を計ろうとすると、
tarai関数は実行されず、promiseオブジェクトが返ってきてしまいます。

> (time (tarai 200 100 0))
cpu time: 0 real time: 0 gc time: 0
#<promise:?>

どこかにforceを書けばいいのかと思ったのですが、いろいろやってもうまく行
きません。

> (time (force (tarai 200 100 0)))
cpu time: 0 real time: 0 gc time: 0
#<promise:?>

どなたか見当のつく方、アドバイスをいただけないでしょうか?


594 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 02:12:54 ]
forceしろ

595 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 08:50:34 ]
timeがpromiseを返してるのでは?

596 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 12:06:33 ]
DrSchemeを触らずに595を書いたけど
見当はずれだったみたい
ごめんなさい
とりあえず
(force (delay (time (tarai 200 100 0))))
したら計算できた
syntaxにおけるimplicit forcingがうまく働いてないのかも
forceはprocedureだから引数がimplicit forceされてforceしようとした値がpromiseじゃなくなってるとか
implicit delayとdelayが違う物みたいだし
doc読んでないので見当違いかもしれないけど


597 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 12:08:30 ]
あ、((lambda (x) x) (time (tarai 200 100 0)))でもいいみたい

598 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 12:11:48 ]
>>596
> (force (delay (time (tarai 200 100 0))))

delayいらないんじゃね?



599 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 12:12:56 ]
(time (tarai 200 100 0))が関数に渡されたときはちゃんと200が返るけど
マクロを含めsyntaxに渡されたときは#<promise:?>が返る

600 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 12:14:05 ]
>>598
(force (time (tarai 200 100 0)))だとforceに200が渡されてエラー
forceは関数だからだと思われる
明示的にdelayしてないとimplicit forceされる

601 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 12:23:37 ]
implicit delayされた物はimplicit forceされる
explicit delayされた物はexplicit forceしなくてはいけない
implicit delayされた物をexplicit forceすることはできない
explicit delayされた物はimplicit forceされない
implicit forceされるのは値を受け取る継続が関数の場合のみ
timeはsyntaxであるから#<struct:promise>でなく#<promise:?>が返される
ってことかな?

602 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 12:34:26 ]
implicit promiseはimplicit forceされると最早implicit promiseでなくなる
他方、explicit promiseはexplicit forceされてもexplicit promiseのまま
(define x (call/cc (lambda (return) (delay (return 'value)))))
x
-> #<struct:promise>
(promise? x)
-> #t
(force x)
(promise? x)
-> #f
x
-> 'value
こんな感じなのかな

603 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 12:42:06 ]
> (time 1)
cpu time: 0 real time: 0 gc time: 0
1
> (time (+ 1 1))
cpu time: 0 real time: 0 gc time: 0
#<struct:promise>

だなあ。

604 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 13:16:33 ]
v372@PPCmacだと
ようこそ DrScheme, バージョン 372 [3m].
言語: Lazy Scheme.
> (time 1)
cpu time: 0 real time: 1 gc time: 0
1
> (time (+ 1 1))
cpu time: 0 real time: 0 gc time: 0
#<promise:?>
になりますね
とにかく構文に渡されたimplicit promiseはimplicit forceされないので
implicit forceされた物を構文に渡さないといけないみたい

605 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 13:24:37 ]
いや違った
構文の値を受け取る継続がトップレベルまたは構文の場合は
implicit forceされない…のかも

606 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 14:14:59 ]
単に値をpromiseで持ち回ってるのではなくて
ちゃんと正規評価してると考えた方がいいのかも
ifやcond遅延評価処理系では関数的な構文
トップレベルでは評価されない
そういった意味では構文はquoteとdefineとset!とlambdaとその派生式のみになる
timeやifやcondやandやorは関数的な構文なので評価されない
これで辻褄が合うと思う

607 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 14:18:15 ]
typo
ifやcond*などの*遅延評価処理系では関数的な構文
つまり(quoteなどの関数では記述できない構文)以外のことね

608 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 14:19:34 ]
(quoteなどの(関数では記述できない構文))以外



609 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 16:13:46 ]
>>603はv360

610 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 16:19:12 ]
ようこそDrScheme, バージョン 360.
言語: Lazy Scheme.
> (fact 10)
3628800
> (time (fact 10))
cpu time: 0 real time: 0 gc time: 0
#<struct:promise>
> (force (time (fact 10)))
cpu time: 0 real time: 0 gc time: 0
※ force: expected argument of type <promise>; given 3628800
> (force (delay (time (fact 10))))
cpu time: 0 real time: 0 gc time: 0
※ force: expected argument of type <promise>; given 3628800
> (+ 0 (time (fact 10)))
cpu time: 0 real time: 0 gc time: 0
3628800

だな。このバージョンのトップレベルはなんかおかしいな。

611 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 16:40:16 ]
・自己評価データは評価される
・変数参照は評価される
・手続き呼出しは評価される
・マクロ使用は展開される
・defineは束縛した変数が参照されるまで評価されない
・quote、begin、lambda、quasiquote、delayは評価される
・構文定義構文は不明
・これら以外は評価されない
・評価される式から参照される式は評価される
という構文周り以外はオーソドックスな実装になってるみたい
末尾再帰がspace leakしないし

612 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 16:44:28 ]
・これら以外は(トップレベルでは)評価されない、に訂正
トップレベル以外で評価される文脈に於いては構文も評価される

613 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 16:47:00 ]
defineはトップレベルでも評価されるが
束縛された式(正しくない表現だけど意図を察してください(^_^;))は
変数が参照されるまで評価されない、という表現に訂正

614 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 16:54:10 ]
v360とv372は評価されなかった構文の値の表記が異なるだけで
挙動自体は同じみたいですね
とにかくifもcondもandもorも正格評価の為に構文とされちゃった物は
関数でラッピングしちゃえばいい
(define lazy-if
 (lambda (pred then-clause else-clause)
  (if pred then-clause else-clause)))
みたいに

615 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 16:57:50 ]
と思ったら
> (force (delay (time (fact 10))))
cpu time: 0 real time: 0 gc time: 0
※ force: expected argument of type <promise>; given 3628800
ここが違いますね
v372だと時間が計測されて3628800が返ります

616 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 17:05:28 ]
time構文はトップレベルでも式が自己評価データの場合は評価されるんだ
でも式が変数参照だと?じゃないpromiseを返す
単にバグバグなだけかも…

617 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 17:12:19 ]
自己評価データでなくリテラルの場合だった

618 名前:567 mailto:sage [2008/02/16(土) 18:03:55 ]
DrSchemeの話題で盛り上がっているところ申し訳ありません.
macro 展開の際に,あらかじめ symbol の束縛関係が参照されると理解しました.
この点についてもう少し具体的に質問させてください (>>589の記述に関係しているのかもしれません).
内部で set! を呼ぶだけの macro Set1 を書いてみました.
;; マクロ定義
(define-syntax Set1 (syntax-rules () ((_ macroSymA macroSymB) (set! macroSymA macroSymB))))
;; 前準備
(define variable 200)
(define newValue 900)
variable ;;==> 200
;; マクロ呼び出し
(Set1 variable newValue)
;; 結果
variable ;;==> 900
もしも処理系が macro 適用時に「手続き set! は第1引数として symbol を取る」という事実を知らないで
無条件に macro に渡された引数の束縛関係を解決 (symbol を束縛値に置換) してしまうのであれば,
(newValue を束縛値 900 に置換するのと同様に) variable も束縛値 200 に置換してしまってから
macro 展開が行われるので,評価対象が (set! 200 900) となってエラーになってしまうはずです.
実際にはそうならないのは,処理系が macro 適用時に
(set! macroSymA macroSymB) が特殊な手続き set! の呼び出しであることを認識して,
(第2引数の newValue のほうは通常どおり束縛値 900 で置換してよいのだが)
第1引数である variable については束縛値で置換することを敢えて行わず,
symbol 「variable」 のまま macro 展開しているからである,と理解してよいでしょうか.



619 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 18:36:03 ]
束縛関係の解決と評価(この場合は変数参照)は違います。
束縛関係の解決とは
C言語風に言えば「変数名がどのアドレスを指すかを確定する事」であり
実際にそのアドレスから値を読み込む事ではありません。
マクロ置換に於いては
syntax-rulesの第一引数のリストに列挙されている識別子のみ
アドレスも使ったマッチングが行われます。
syntax-rules ()のように識別子が無い場合はアドレスはマッチングに利用されません。
アドレスはマッチング、すなわちどの置換パターンを利用するかを決定するのにのみ利用されるだけです。
そして置換された後の式によって変数が参照されるかどうか決まります。
この場合は置換後の式が(set! variable newValue)なのでvariableは評価されません。
set!の第2引数は評価されるのでnewValueが変数参照されて900となります。
しかし置換後の式が例えば(+ variable newValue)ならば手続き呼出しですので
+が変数参照されて#<procedure +>に
variableが変数参照されて200に
newValueが変数参照されて900に評価されてから
手続きが呼び出されます。

620 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 18:44:05 ]
(A B C)のリストが評価される場合(A B Cは識別子)
Aが構文に束縛されているかどうかを調べ
・構文に束縛されている場合
 ・primitive構文に束縛されているなら、その評価規則に従って評価します。
 ・マクロに束縛されているならパターンマッチを行い、テンプレートに従って置換した後、その式を評価します
・場所に束縛されているなら
 ・手続き呼出しを行います。AとBとCはすべて評価されますが、順番は決まっていません。
  AやBやCが評価されるときに初めて変数参照として値が読み出されます

621 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 18:52:27 ]
マクロ置換された式がリストならまた620の用に評価されます。
primitive構文はdefine、if、quote、lambda、set!のみで
他の構文は全てマクロです。(R5RSの場合。処理系独自のprimitive構文もあり得る。)

622 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 18:56:49 ]
(A B C)という手続き呼出しの場合
AとBとCが評価される順番は決まっていませんが
手続きが呼び出される前には評価されます。
つまりAとBとCが評価された後にAが束縛されていた場所の値を手続きとして呼び出します。
もしAの場所の値が手続きでなければエラーとなります。

623 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 19:07:03 ]
マクロのパターンマッチングは式の形(とリテラル識別子の場合は束縛されている場所)によってのみ行われます
なので例えば
(define x '(1 2))
(define-syntax foo
 (syntax-rules ()
  ((foo (x y)) (list y x))
  ((foo z) (list z))))
(foo x)
-> '((1 2))
となります。
つまり(foo (x y))にではなく(foo z)にマッチした訳です。
(foo x) --(置換)-> (list x) --(部分式の評価)-> (#<procedure list> (1 2))
-> '((1 2))
というわけです。

624 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 19:35:58 ]
リテラル識別子とのマッチングは
正しくはアドレスではなく束縛によって行われますので
構文に束縛されているリテラル識別子は
同じマクロ変換子に束縛されている識別子にマッチします。
構文に束縛されている識別子は
場所には束縛されていませんので
アドレスという概念は当てはまりません。
ローカルな変数束縛によって構文束縛が隠蔽される事も
ローカルな構文束縛によって変数束縛が隠蔽される事もあります。
なので束縛の種類とその束縛されているモノと字の綴りが同じ識別子のみが
リテラル識別子にマッチするという方が正しいでしょう。

625 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 19:48:28 ]
4s/マクロ変換子/構文/

626 名前:567 mailto:sage [2008/02/16(土) 21:05:57 ]
>>619 - >>625
早速のご返答ありがとうございます.
いま R5RS も見ながら考えさせていただいていますが,もう少し時間をいただきます.

問題の本質とは少しずれますが,私が混乱していた原因の一つに,syntax-rules の
第1引数である literals に含まれている literal-identifier についての誤解があったようです.
「literal」という名前から,字面の一致だけを見るものだと思いこんでいましたが
正しくは,R5RS や >>573 さんはじめ上の書き込みにもさんざんあるように,
literal-identifierは
>>583:
>ともに未束縛であるか
>或いは同じ束縛(例えばトップレベル変数)を持つ場合にのみマッチする
ということなんですね.思いこみで記述が頭に入っていませんでした.

なお,577:で
5s/template上のsymbol/pattern上のsymbol/
でした.

627 名前:593 mailto:sage [2008/02/18(月) 00:57:16 ]
皆さん、ありがとうございます。遅くなってすみません。
途中から議論が分からなくなってしまったのですが、>>596さんのコードを実
行したところ、tarai は実行されますが、表示される時間は 0 です。

> (force (delay (time (tarai 800 400 0))))
cpu time: 0 real time: 0 gc time: 0
800

すみませんが、これはどうにかならないでしょうか?

628 名前:593 mailto:sage [2008/02/18(月) 00:59:59 ]
あ、バージョンは最新の 372 です。




629 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 01:01:00 ]
promise作って終りかw

630 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 10:52:21 ]
ちゃんと800が返されてるから
正しいのでは?
タライ回し関数は遅延評価で計算すると
正格評価にくらべて格段に速い

631 名前:630 mailto:sage [2008/02/18(月) 11:04:00 ]
timeで計測できないくらいの短時間で計算できてるって意味です

632 名前:593 mailto:sage [2008/02/18(月) 13:59:55 ]
いや、もっと時間はかかってます。
(force (delay (time (tarai 1000 500 0)))) を実行してみてください。
これで0秒なのは、おかしいでしょう?

633 名前:593 mailto:sage [2008/02/18(月) 14:02:07 ]
と言うか、先に0秒という計測結果が表示されてから、10秒ほどして 1000 と
いう計算結果が表示されるのです。もしもっと早いマシンをお使いなら、引数
を適宜増やしてお確かめください。


634 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 14:48:40 ]
確かに
time構文はLazy Schemeでは使い物にならないと考えた方がいいかも

635 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 15:18:20 ]
たらいまわしべんちでtime構文が使えないなら、Lazyである意義などない!

636 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 16:00:56 ]
こんなんで我慢してちょ

(define (bench exp)
__(let* ((start (current-milliseconds))
_________(value exp)
_________(end (current-milliseconds)))
____(display start)
____(newline)
____(display value)
____(newline)
____(display end)
____(newline)
____(display (- end start))))

ミリ秒でしか測れないし
余計な出力もあるのがダサいけど

637 名前:593 mailto:sage [2008/02/18(月) 17:06:55 ]
>>636
ありがとうございます。ちゃんと動きました。
ありがたいことに、自分にも隅々までよく分かるコードです。
しかし、遅延評価であるがゆえに、逆に副作用だらけになってしまったのが、
少し泣けます。

638 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 00:54:51 ]
正規表現ってRnRSにもSRFIにも入ってないの?



639 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 01:05:04 ]
community.schemewiki.org/?scheme-faq-programming#H-1w56qpn

640 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 12:33:26 ]
実装はいくらでもあるが、標準仕様がないのはなぜかと問いたい
共通語がないと不便じゃないか

641 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 12:45:47 ]
R6RSでUnicode化も決まったので、"Beyond R6RS"に入ってます。
schemers.org/Documents/Standards/Charter/status-jun-2006/status-jun06.html#g11

642 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 14:19:47 ]
正規表現は構造を文字列で表現するとこがLISPっぽくない。
まあ普及しちゃったからしょうがないけど、必要悪だろ。

643 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 15:01:38 ]
LISPから必要悪を取ったらλしか残らない

644 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 15:40:04 ]
すみません、MzSchemeやGaucheで、実行中のスタックの遷移を表示するにはど
うしたらよいでしょうか?

www1.ocn.ne.jp/~scheme/petite-start.html
↑のページで紹介されている、ChezSchemeの trace関数のようなものです。


645 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 15:50:08 ]
DrSchemeでプロセス間通信とかできますか?
Schemeにはそもそもプロセスという概念が無い?
今はただ関数定義程度の練習レベルです。

646 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 15:51:20 ]
つまり、Schemeで出来ること、あるいはSchemeの用途
がイマイチ分かってないということです。

647 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 18:32:37 ]
gccでプロセス間通信とかできますか?
Cにはそもそもプロセスという概念が無い?
今はただ関数定義程度の練習レベルです。
つまり、Cで出来ること、あるいはCの用途
がイマイチ分かってないということです。

648 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 18:39:45 ]
>>647
そうか。意味不明だったか。確かに。

どういう分野に活かしていくのが普通なんでしょうか?
例えば、CやC++ならネットワークプログラミングとかOSとか
デバイスドライバとか作成しますが、Schemeのアプリケーション
とはどういったものになりますか?コンパイラ作成用途とかになる
んですかね?



649 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 20:07:12 ]
そういうのはライブラリに拠るんだから一概にどうとは言えないよ。
まあ記号処理には強いだろうね。

650 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 20:11:01 ]
>>649
記号処理ですか。未知の分野なのでもう少し精進して
調べて見ます。

651 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 20:42:31 ]
>>644

MzScheme だとライブラリを使えばtrace、untraceもOK。
> (require (lib "trace.ss"))
>


652 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 20:51:09 ]
>>645

Petite Chez Scheme だとprocessを使って
他のプロセスにデータを送れたよ。
fprintを使うんだったかな。

>>650
数式処理には向いていると思う。
他にもいろいろと応用はあるんじゃないかな。

653 名前:644 mailto:sage [2008/02/20(水) 21:35:05 ]
>>651
MzScheme, DrSchemeでうまく行きました。
ありがとうございました。

Gauche はこんな感じのようです。

・トレース - 結城浩のSICP日記 - sicp
sicp.g.hatena.ne.jp/hyuki/20060507/trace


654 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 21:41:28 ]
>>650
使用言語の選択を誤っていると思う
あなたの場合Lispを選択する意味はないのではないか
一般に手に入る資料が豊富な分C/C++でやるのがよい

655 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 21:44:42 ]
>>654
C/C++は習得済みで業務で使用してます。
Schemeでプロダクトコード書くわけではないので。

656 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 21:58:03 ]
lispやってる奴がもれなく超人に見える
だからやりたい
とか言う程の物さ

657 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:16:40 ]
>>655
言語の話とライブラリの話がごっちゃになってないかな。

言語の特徴としては、再帰的な処理の記述とか、
メタなプログラミングが楽とか色々あるけど。
そういうことが知りたいんじゃないんだろうし。

Schemeのアプリケーションって言われても、
ウェブアプリケーションサーバ書いてる人もいれば、
.NET向けのアプリケーションを書くために処理系を実装してたり、
日常的に使うスクリプトをSchemeで書いてる人もいたりして様々。

658 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:22:45 ]
>>657

>再帰的な処理の記述とか、 メタなプログラミング
ここが勉強したいと思ったきっかけです。

>Schemeのアプリケーションって言われても、
>ウェブアプリケーションサーバ書いてる人もいれば、
>.NET向けのアプリケーションを書くために処理系を実装してたり、
>日常的に使うスクリプトをSchemeで書いてる人もいたりして様々。

色々できるんですね。ありがとうございます。



659 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:30:23 ]
>>658
ttp://practical-scheme.net/index-j.html

にある文章をいくつか読んでみたらどうだろう。ここのスレの人とかが、
何故敢えてLispやSchemeを使うのか、理解する助けになると思う。

660 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:32:48 ]
たぶん、プロセス間通信みたいな処理が好きな人は
SchemeよりEmacs Lispの方が楽しめると思う。
CL使わないとLispらしさのかけらもないコードになっちゃうけど。






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<210KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef