Masatake YAMATO
yamat****@redha*****
2010年 8月 25日 (水) 23:13:27 JST
> From: Masatake YAMATO <yamat****@redha*****> > Subject: [Gauche-devel-jp] handing keyword in ref > Date: Wed, 25 Aug 2010 19:37:49 +0900 (JST) > >> get-keywordの箇所でrefを使いたくなることが良くあります。 >> こういったものを書いてみたので良かったら導入を検討してもらえませんか。 >> >> 大和 >> >> >> >> (define-method ref ((obj <list>) (keyword <keyword>)) >> (get-keyword keyword obj)) >> (define-method ref ((obj <list>) (keyword <keyword>) fallback) >> (get-keyword keyword obj fallback)) >> (define-method (setter ref) ((obj <list>) (keyword <keyword>) val) >> (let1 r (memq keyword obj) >> (if r >> (set-cdr! r (cons val (cdr (cdr r)))) >> (set-cdr! (last-pair obj) (list keyword val))))) > > <list>はkeyword-value listとは限らない、というのが問題だと思います。 > > 例えば空リストに対しては(setter ref)はうまく動かないですよね。 > まあそれはドメインエラーだとする解釈も出来なくはないですが、 > 基本的なメソッドなのにすべての<list>に対して動かない、というのは > 危険な感じがします。 > > もともとLispのリストは、型としては単一で、「使う側が好きなように > 解釈する」というユルさが利点でもあり欠点でもあります。 > get-keywordを使う場合はリストをplist形式のマップとみなしている > わけですが、同じマップとしての使い方でもalist形式がありますし、 > また単なる要素の集合とみなすこともできます。 > これは使い手の解釈に委ねられているので、<list>としてディスパッチする > メソッドがひとつの見方を固定してしまうのはちとまずい。 > むしろ、使う側がget-keywordなりassocなりmemberなりの > 個別の関数を用いることで、「今はリストを(plist|alist|集合)と > みなしているよ」と明示できることの方が重要ではないかと思います。 うーん、なるほど。ごもっともです。 > なお、テストコードでリテラルリストを変更してます。気をつけてください。 > >> (test* "ref+set! for keyword(0)" >> '(:a 1 :b 9 :c 3) >> (begin >> (set! (ref x :b) 9) >> x)) > > それと、上の(setter ref)の定義だとkeyword-value listの > valueのところにたまたま一致するキーワードが入ってるとまずいですね。 添削までしていただいて、すいません。勉強になります。 Subjectから外れてしまうのですが、キーワードとgaucheのライブラリのデザインに ついて常々知りたいと思っていたことがあるので教えて頂けないでしょうか? open-output-fileのキーワード引数に:if-existsがあります。infoによればここに 値として :supersede :append :overwrite :error が指定できることになっています。そこで質問なのですがこれがシンボルでは なくキーワードとしたのはどういった経緯からでしょうか? 最初に学んだlispがemacs lispだったのですが、キーワード引数の値部分にキー ワードが来るというのは見たことがありませんでした。この点でgaucheを使っ ているととまどうことがあり、値部分もキーワードとしている背景が知りたく なりました。 大和