[Gauche-devel-jp] 辞書とイテレータ

Back to archive index

Kimura Fuyuki fuyuk****@hadal*****
2003年 1月 18日 (土) 20:25:55 JST


ここしばらく <dictionary> フレームワークについて考えていたのですが、こ
れが簡単そうに見えて案外難しい。で、煮詰まったので知恵を貸してください。

(ここでは hash-table を例に挙げますが、実際には辞書的な動作をするオブ
ジェクト全般についての話と思ってください)

たとえば、ハッシュから値が偶数である要素を抜く処理を考えてみます。現状
では

(hash-table-for-each
 hash
 (lambda (key val) (when (even? val) (hash-table-delete! hash key))))

となりますが、delete! でキーの再検索(*)がかかってしまいます。

(*) 正確な言い方ではないですが、たぶん意味は伝わるでしょう。内部ではポ
インタを押さえているはずなのにそれを使えないのはもったいないということ。

すべての値を倍にして再格納する処理はどうでしょう。

(hash-table-for-each
 hash
 (lambda (key val) (hash-table-put! hash key (* val 2))))

これも put! でキーの再検索がかかります。

なんとかこういった問題をうまく解決できないものでしょうか。ちなみに上の
例は、いずれもSQLならごく簡単に書けて、(たぶんRDB内部では)効率的に実行
してくれるであろう処理です。

個々の問題は下に挙げるような小手先の対策でもけっこうなんとかなるのです
が、一般的な解決は

「回っている最中に要素の更新/削除を効率良く実行できるイテレータ」

になりそうな気がしています。

何かいいアイディアとか、この言語が参考になるよとか、俺様のすばらしい実
装を見れとかあったら教えてください。

*

<こうすればなんとかなるという例>

要求: 条件に一致する要素を抜きたい

対処: hash-table-remove! をCで書く

用例:

(hash-table-remove! hash (lambda (k v) (even? v)))

要求: 値を加工して効率良く再格納したい

対処: hash-table-update! をCで書く

用例:

(define (hash-table-push! hash key val)
  (hash-table-update! hash key (lambda (k v) (cons val v))))

要求: delete! される要素の後始末をしたい

対処: hash-table-delete! がオプショナルな後始末関数を取るようにする
      or 削除した値を返すようにする

用例:

(hash-table-delete!
 hash key
 (lambda (k v) (print "i'm going to die..." k v)))

要求: 条件に一致した値を加工して効率良く再格納したい

対処: しらん

ということで、きりがない。

*

全然関係ないけどtypoの修正をつけておきます。今月は1個しか見つかりませ
んでした(すごい)。あと、slot-push! の説明がちょっと嘘っぽいです(except
がexceptじゃないような)。

--- doc/gauche-ref.texi	16 Jan 2003 03:52:53 -0000	1.345
+++ doc/gauche-ref.texi	18 Jan 2003 09:39:53 -0000
@@ -14058,7 +14062,7 @@
 @end defun
 
 @defun slot-bound? obj slot
-Returns true if object @var{obj}'s slot @var{slot} is bount, 
+Returns true if object @var{obj}'s slot @var{slot} is bound, 
 otherwise returns false.
 
 If the object doesn't have the specified slot, a generic function

-- 
木村 冬樹




Gauche-devel-jp メーリングリストの案内
Back to archive index