Gauche > Archives > 2010/05/09

2010/05/09 05:47:52 UTCshiro
#
@cametan_001 @valvallow 変数用と手続き用で分かれてるわけじゃないよ RT そうそう。letがλ式束縛して、名前を参照出来れば二つも要らない筈なんですよ。多分、実装上の効率の理由でああなってんのかな?でもdefineと比較すると明らかに対称性が崩れてるんじゃないのか、とか思うんです。局所だと変数用と手続き用が分かれてるわけですから。 http://twitter.com/cametan_001/statuses/13651398170
#
効率も関係ない。純粋にスコープの問題。
2010/05/09 05:51:42 UTCvalvallow@twitter
#
letとletrecが別々な理由がわからなくて^^;
2010/05/09 05:54:22 UTCshiro
#
スコープが違うだけです。
#
どっちか片方だけにするのは難しい (MLでも両方ある)
#
敢えて選ぶとすればletrecかな。letは簡単にlambdaで書けるので。
2010/05/09 06:02:44 UTCvalvallow@twitter
#
letrecがあればletはなくても良いのでは、などと話していました。letrecじゃなくてletでなければ、という例がわからなかったもので・・・
2010/05/09 06:04:27 UTCshiro
#
@valvallow (let ((x (+ x 1))) ...) みたいなのはletrecでは書けないですね。まあ変数名を変えればいいんですが。
2010/05/09 06:08:45 UTCvalvallow@twitter
#
なるほど・・・ RT : shiro: @valvallow (let ((x (+ x 1))) ...) みたいなのはletrecでは書けないですね。まあ変数名を変えればいいんですが。 http://bit.ly/9jeRbu
#
ありがとうございました!
2010/05/09 06:20:51 UTCshiro
#
@valvallow @cametan_001 letrecの方が先行してたっていうのはそうかもしれない。Schemeの最初の論文に既にlabelsがあって、これは再帰的定義に使える(CLのlabelsと同じ)。論文ではHewittが使ってた記法を頂いたとある。
#
最初のScheme論文にletはない。で、MACLISPのマニュアルにはletが出てると思ったけど1983年版だった。Schemeも最初の版はMACLISPで実装されてて、ソースもあるけど、ソース中でLETは使っていない (LAMBDAを局所変数導入に使っている)
#
RRSにはletが出てくるから、letを導入したのはSchemeっていう @cametan_001 説は正しいかも。
2010/05/09 11:57:52 UTCshiro
#
むー、仕事でちゃんとした限定継続が必要になった。どーしよーかなあ。
2010/05/09 12:10:03 UTC(び)
#
オリジナルの論文では、処理系のプリミティブを使って実装してましたっけね。って、限定継続って部分継続と同じものですか?
2010/05/09 12:12:37 UTCshiro
#
同じものです。「ちゃんとした」というのは、resetとshiftで切り取った継続を保存しておいて別のスレッドで再開したいのです。
#
call/ccで切り取ると継続の「底」にあるC stack pointerまで保存してしまうので、他のスレッドで再開するのがうまくない。
2010/05/09 12:13:27 UTC(び)
#
Kahuaの実装って、スレッドをまたぐとおかしなことになるんでしたっけ?
#
あーなるほど
2010/05/09 12:14:00 UTCshiro
#
おかしいというより、今はGauche自身のチェックにひっかかります。
2010/05/09 12:15:11 UTC(び)
#
よそのスレッドのスタック領域を触ると例外が上がる?
2010/05/09 12:15:59 UTCshiro
#
再開時点で、C stackに矛盾があると例外があがります。
#
対症療法としては、スレッド内で作られる継続をデフォルトでスレッド開始時からの限定継続ってことにしてしまう、という手もあるにはあるので迷ってます。
#
そうしたらkahuaの実装でも使えるはず。
2010/05/09 12:19:56 UTC(び)
#
うー、理解できてるか自分で怪しい...
2010/05/09 12:25:12 UTCshiro
#
GaucheのSchemeコードはどんな場合であれ、一番最初はCから呼ばれてるわけです。Scm_Evalとかで。そして、SchemeからCへ「戻る」ことは一度しかできません (Cは呼び出した関数から2回以上戻ってくることを想定してない)。
#
なので、継続は捕まえた時点のCのスタックを覚えてて、呼び出される時にそのCスタックが全部生きているか (= 呼び出し時点でのCスタックが、覚えているCスタックと同じか深い位置にあるか) をチェックします。
#
別スレッドで捕まえた継続だと、含まれてるCスタックは呼び出す時点のCスタックと無関係なので、このチェックで跳ねられると。
#
まてよ。呼び出し時じゃなくて、その継続から戻ってきてCに抜ける時にチェックすればいいのかな? それならCに抜ける前に別の継続を呼び出しちゃえばおかしなことにはならないぞ。
#
なんで継続呼び出し時にチェックしてるかというと、継続補足(A)->Cルーチン呼び出し->Schemeルーチン(B)->継続呼び出し、というケースでは、(B)と(A)でCのスタックが異なるので(B)から(A)へlongjmpしてCスタックを巻き戻しとかないとならない。
#
なので(B)の下位に(A)がないとlongjmpできないや、ってことになるわけだけど。
#
(B)の下位に(A)が無い場合はそうマークしておいて、(B)からCルーチンにもどるところで例外を投げればii
#
いいような気がしてきた。