Scheme でポートをラッピングするとき
- SaitoAtsushi
- 1395
- 0
- 0
- 0
R6RS にはポートをコピーする機能ないのか。 transcoded-port があるくらいだから内部的にはそういう機能が必要なはずだと思うんだけど。
2015-02-26 04:24:03@SaitoAtsushi transcoded-portは受け取ったバイナリポートを閉じるので、実装によってはコピーの必要がないです。
2015-02-26 06:41:40@tk_riple 閉じるにもかかわらず状態を引き継ぐのでコピーと表現しました。 ポートをラップするときは元のポートにアクセスして欲しくないことがあるので閉じたいんですけど、そういう方法がないのでどうしたものかなと。
2015-02-26 09:17:33@SaitoAtsushi なるほど。実装的な面で考えると、ポートの呼び出しが特定のクロージャ内かどうかを判別しないといけないので、かなり難しいんじゃないかなぁと。
2015-02-26 14:10:15@tk_riple そうですか? ポートの複製をとってから元のポートを無効 (クローズ) にできればいいだけだと思うのですが。
2015-02-26 14:49:14そうは言っても、カスタムポートに対してポートのコピーをどうするのかというのはやはり難しい気がする。特にクローズが捕捉したポートも閉じる場合とか。
2015-02-26 15:05:25内容を全部input/outputポートに流し込んで、要らない側を閉じればとも思ったが、コピー元が出力ポートだと詰むな。思った以上に厄介な問題なのかもしれない。
2015-02-26 15:15:43ポートをファイルハンドルとみなせば、全てのハンドルをクローズしたときに実体もクローズされるようにすれば充分なんじゃなかろうか。 (参照カウント方式)
2015-02-26 15:16:44@tk_riple 一般的なセマンティクスを決められる気がしないのでそもそもなぜそれをしたいと思ったか気になる…生のポートだってどこまでの外部リソースが共有されるかで曖昧性ができるだろうし。
2015-02-26 15:19:58.@anohana @tk_riple バイナリポートをテキストポートに切り替える transcoded-port は元となるバイナリポートを閉じたりするんですが、それを一般化してポートをラップしたときに元のポートを閉じれないかというのが元です。
2015-02-26 15:26:54@SaitoAtsushi @tk_riple ああなるほど。元のバイナリポートを閉じる意図はリソースに対するシングルコピー(複数箇所からアクセスしないようにする)なわけだけど、元がカスタムポートだと困るって話かな。とするとクローズとは別の「他からアクセスさせない仕組み」が要るか
2015-02-26 15:38:55@anohana @SaitoAtsushi この「他からアクセスさせない仕組み」の上手い案がないんですよね。ポートが環境を知るくらいしかなさそうな気がしてるのですが。
2015-02-26 15:44:53@anohana @tk_riple ポートを複製してから閉じるんじゃなくて C++ のムーブセマンティクスみたいに元ポートの情報をもった新しいポートを作ると同時に元のポートを無効にしてしまうという「移動」が出来れば充分に用を成すと思ったのですがどうでしょう。
2015-02-26 15:45:26@SaitoAtsushi @tk_riple ですね。実装上は一段間接参照かまして、本体への新たな間接参照を作成&オリジナルの間接参照を無効にする、でいけると思いますが、汎用的な仕様にするのはちとめんどうかも。
2015-02-26 15:48:58この場合、共有リソースのことまで考える必要があるのかは疑問ではあるのだが。コピーして元のポートは閉じるってユースケースだと問題になりそう。
2015-02-26 15:57:09@tk_riple @SaitoAtsushi 所有権の移動とポートのクローズは全く別にすべきですね。で、ムーブ後の元ポートをクローズしたらどうなるかだけど、call-with系でリソース開放を確実にしたいとすれば、無効間接参照でもクローズだけは効く方がいいかなあ。
2015-02-26 16:03:38@anohana @SaitoAtsushi それだと元々の「他からアクセスさせない仕組み」が構築できないような。コピー&クローズで実装だとクローズの際にリソースが閉じてしまうのでは?
2015-02-26 16:09:34@tk_riple @SaitoAtsushi はい、所有権の移動は間接参照でやるってことにして、無効フラグが立った間接参照ではクローズ以外の操作はエラーにする。クローズについては元の参照でも新しい参照でもok。重複クローズok。
2015-02-26 16:12:02