#Lisp系の言語をさわっていて、迷うことの一つに2つの要素をconsで扱うかlistで扱うかということがあるので、wilikiにページを作って見ました。
#Gauche:Pair
http://practical-scheme.net/wiliki/wiliki.cgi?Gauche%3aPair
#Lisp:Pair
http://practical-scheme.net/wiliki/wiliki.cgi?Lisp%3aPair
#手続きがn-in,m-outなように、dictionaryもn-in,m-outならばいいのではないかと思うのです。n個のkeyに対してm個の多値を返す。そのインターフェースをどうしたものかと、いろいろ考えるのですが、うまくまとまりません。(まとまらないので、とりあえず、ここに流してみることにしました。)
#(1)n個のkeyに対して、異なる等価判定(eq?,equal?など)をしなければならない。(2)可変の長さをもつパラメータが2種類(key,value)があるので、これを指定するインターフェース (3) (2)と同時に与えるオプショナルなパラメータ。など
#また、いまのdictinaryフレームワークではfallbackが定数なのですが、これをf手続き(applicable)にできれば、若干柔軟な処理ができそうな気がします。
#SourceForge.net: Gauche:
http://sourceforge.net/mailarchive/message.php?msg_id=29772717
にて指摘されているように、多値の関数のメモ化を考えるならば、dictionaryも多値になればいいような気がしたのでした。
#gosh> (sys-setenv "TMP" "~/tmp")
#<undef>
gosh> (sys-getenv "TMP")
"~/tmp"
gosh> (sys-setenv "TMP" "hoge")
#<undef>
gosh> (sys-getenv "TMP")
"~/tmp"
gosh> (sys-setenv "TMP" "hoge" #t)
#<undef>
gosh> (sys-getenv "TMP" )
"hoge"
gosh> (cond-expand [gauche.sys.setenv (print "ok")] [else (print "NG")])
NG
#<undef>
#cond-expandではsys-setenvがつかえないことになっているのですが、使えるのですが、なにがまずいのでしょうか?
#バグでした。直しました > gauche.sys.setenv
#m-in, n-outというdictionaryは考えられなくはないですが、APIが複雑になるだけであまり良いことはないような気もします。とはいえ欲しければ現在のdictionaryの上にそういうのを作ることはできるでしょうから (性能は別として)、試しにつくって具合をみてみたらどうでしょうか。なお、fallbackを定数にすべきかthunkにすべきか、というのは昔からある議論で (hashtableのインタフェースに関して過去のsrfiやrnrsの議論を見てください)、どちらも一長一短があります。
#m-in,n-outの辞書ですが、m-inについてはtrieのようなものがあるのかなとか考えます。同じprefixという括りかたは、関数の部分適用に対応するように思えます。(辞書のcurry化) m-outについてはちょっとどうしたものか。putのインターフェースとか、もんもんと悩んでいます。
#fallbackを定数にすべきかthunkにすべきか、ということなのですが、thunkではなく、hashtableとkeyを受け取って、それを処理するという考えでした。ともかく、srfi、rnrsを調べてみます。
#ありがとうございました。
#ああなるほど。とはいえdict-getを呼び出す人は既にdictとkeyを持っているので、 (dict-get dict key (lambda () (fallback dict key))) とくるめば同じことですね。本質的な違いはないかと思います。
#m-inを階層化するというアイディアはおもしろいですね。実際、そういう階層的な辞書構造を作ることはしばしばあるので、<dictionary>の上に何らかのフレームワークを組めると良いかも。n-outについてはまだ正直、リストじゃいかんの? という感じです。数が固定されていることに意味がある?
#いや、ShiroさんのMLの多値の関数をメモ化することができるか?というくだりに、どうもひっかかっていて・・・・
#辞書を多値にしたらどうなの?とか考えたのでした。
#dict-getを継続渡しにするとか、いろいろ
#出力に関しては、(apply values (dict-get ...)) で簡単に多値に変換できるんで、多値にしてとりわけうれしいシチュエーションというのがイメージできないというか。辞書のインタフェースの一部として「必ず3個の値が返ってくる」とかがわかると何か便利である、とかそういう話はありえるのかなとは思うけど具体例がまだ思いつかない。
#そうなのですが、多値のジェネレータを原理的には作成可能なこともあり、辞書も原理的には可能かなあとか。
#なにに役にたつのかは、よくわかりません。
#多値というインターフェースがデータ構造の表現となったらどうなるのか?みたいな。
#わたしの理解の範囲では、多値は手続きの世界の話みたいなのですが、それだけだろうか?のような謎かけをしています。
#コレクションもイテレータ次第で多値になるということもあります・・・・
#どうも、まとまりません。(汗
#データをパイプのように流してゆくことを考えると、パイプの合流や分岐がn-inやm-outに相当しますね。ただ、そういう世界ってのは手続きのネットワークに綺麗にマップできるんで、辞書とか具体的なデータ構造を持ち込む必要があるのかな? と思います。辞書を取ってn-in/m-outなマッピング手続きを作れば、そういうネットワークに組み込むことはできるわけですよね。
#つまり私のイメージだと、データを流してゆく機構の方は手続きで、辞書だのコレクションだのという具体的なデータ構造は「流れるデータ」の方にあるものだと考えるとすっきりするんじゃないの、ということです。わざわざ手続き以外の構造を頑張って機構の方に組み入れる必要があるのかな、という。
#なるほど。
#いま、思いついたのですが、dictionaryが多値になったとすると、値のないdictionaryは自然に定義できて、(values)を返せばよいということになるかなとか。
#そうすると、集合はdictionaryのサブクラスと見なせる、のかなとか。