再開

ええと、Scm_MakeSubr の理解が微妙。関数名の文脈 (??) 的には手続きオブジェクト作る、って意味か。
ええと微妙なのが Scm_Setter の定義における以下の箇所。

        /* fallback to (setter object-apply) */
        return Scm_MakeSubr(object_setter, (void*)proc, 0, 1,
                            SCM_OBJ(&object_setter__NAME));

Scm_Setter に渡される ScmObj 型の proc が SCM_PROCEDUREP でない場合なブロック。もしかするとこのあたりは「一般化された set!」の理解が微妙だからかなぁ。もっかいドキュメントをよく読んだ方が良さげ。

ドキュメント読んだ

ええと、一般化された set!] によれば

(set! (foo expr ...) val)

((setter foo) expr ... val)

に変換される、との事。Gauche では compile.scm でこの変換を行なっている、のかな?
ココサブさんは以下の式を使用例で挙げている。

(disasm (lambda () ((setter car) list item)))

これは car という手続きオブジェクトが setter 持ってるケイスか。あ、このインストラクションの並びはなんとなく見たコトあるぞ。

;; 0 GREF-PUSH? #<identifier user#list>; list

;; 2 GREF-PUSH? #<identifier user#item>; item

;; 4 GREF #<identifier user#car>; car

;; 6 SETTER ; (setter car)

;; 7 TAIL-CALL?(2) ; ((setter car) list item)

;; 8 RET

どこだったか ... (を

うーん

Scm_MakeSubr の定義が以下。

ScmObj Scm_MakeSubr(ScmSubrProc *func,
                    void *data,
                    int required, int optional,
                    ScmObj info)
{
    ScmSubr *s = SCM_NEW(ScmSubr);
    SCM_SET_CLASS(s, SCM_CLASS_PROCEDURE);
    SCM_PROCEDURE_INIT(s, required, optional, SCM_PROC_SUBR, info);
    s->func = func;
    s->data = data;
    return SCM_OBJ(s);
}

てーか、段々ワケワカになってきた。Scm_Setter に渡される proc が手続きオブジェクトではない、という事はどーゆー事か、と思いつつ確認。

gosh> (define l '(1 2 3))
l
gosh> (setter l)
#<subr object-setter>
gosh> 

これが正に問題となってるソレですな。

gosh> ((setter l) l 'a)
*** ERROR: invalid application: (#0=(1 2 3) #0# a)
Stack Trace:
_______________________________________
gosh>

(setter l) が戻すのは手続きオブジェクトなんじゃないの??といいつつ物凄く脱線している (?) コトに気がついた。あるいは has-setter? が #f を戻す場合にどんな挙動になるのかなぁ、ってこれも脱線ッスか?? (を

もう少し

脱線してみる。

gosh> (has-setter? list)
#f
gosh> ((setter list) l 'a)
*** ERROR: invalid application: (#f (1 2 3) a)
Stack Trace:
_______________________________________
gosh>

むむ。そのままっちゃそのまんまだ。(何

掘る

object_setter あたり。まず、Scm_GenericObjectSetter って何だろ。掘ってみると class.c にて以下。

SCM_DEFINE_GENERIC(Scm_GenericObjectSetter, Scm_InvalidApply, NULL);

Scm_InvalidApply は class.c にて以下。

/* fallback of object-apply */
ScmObj Scm_InvalidApply(ScmObj *args, int nargs, ScmGeneric *gf)
{
    Scm_Error("invalid application: %S", Scm_ArrayToList(args, nargs));
    return SCM_UNDEFINED;
}

あらら。てーコトは proc が手続きオブジェクトではない場合はエラーね、って理解で良いのかなぁ。何故に

        return Scm_MakeSubr(object_setter, (void*)proc, 0, 1,
                            SCM_OBJ(&object_setter__NAME));

って書き方になってるか、については絶対根拠があるはず。
これ以上脱線すると微妙なので、レビューのコメント書こ。