gencomp 確認 (7)

なんか標題から話が脱線してる気がしますがそのまま続けます。
@ の定義にあるコメント (lib/gauche/cgen/literal.scm)

;; NB: a small experiment to see how I feel this...
;;  [@ a b c d] => (ref (ref (ref a b) c) d)

ちなみにこの @ 使ったスロット参照は lib/gauche/cgen 以下でしか使われていない模様。ネットに情報があまりなくって 0.8.14 のソース見たら @ が ~ になってるのでしょうか。0.8.14 だと lib/gauche/experimental/ref.scm で定義されてるみたい。
0.8.14 だと gauche.experimental.ref は gencomp も use している模様。名前を変えてモジュールとして gauce.cgen.literal から出しているのには何かの意図があるんでしょうね。gauche.cgen なモジュール以外で use しているのは上記の通り gencomp のみな模様。
作り自体はさほど違わないみたい (?) なので気にせず確認してみたいですが、ここまでのプロセスで微妙に力尽き気味だったりしてます。

続き

再度引用。

(define @
  (getter-with-setter
   (case-lambda
     ((obj selector) (ref obj selector))
     ((obj selector . more) (apply @ (ref obj selector) more)))
   (case-lambda
     ((obj selector val) ((setter ref) obj selector val))
     ((obj selector selector2 . rest)
      (apply (setter ref) (ref obj selector) selector2 rest)))))

基本的に @ は手続き、ってコトは getter-with-setter は手続きを戻すはず。定義は scmlib.scm にて以下。

(define (getter-with-setter get set)
  (let ((proc (lambda x (apply get x))))
    (set! (setter proc) set)
    proc))

上記手続きの引数 get, set も同様に手続きである、と見ると @ の中で呼ばれてる case-lambda も同様に手続きを戻すと思われる。case-lambda は lib/gauche/procedure.scm で define-syntax されてて以下。

(define-syntax case-lambda
  (syntax-rules ()
    ((case-lambda (arg . body) ...)
     (make-dispatcher (list (lambda arg . body) ...)))
    ((case-lambda . _)
     (syntax-error "malformed case-lambda" (case-lambda . _)))))

直下に make-dispatcher 手続きの定義もあり。

;; support procedure
(define (make-dispatcher closures)
  (lambda args
    (let ((len (length args)))
      (cond ((find (lambda (p) (procedure-arity-includes? p len)) closures)
             => (cut apply <> args))
            (else
             (error "wrong number of arguments to case-lambda:" args))))))

これも手続きオブジェクト戻してるのは分かる。このあたりから微妙になってきつつあります。なんとなく繋りはイメージできてるんですが、具体的な挙動がイメージできてません。へろへろ杉で同じトコを loop してる気がします。

も少し

上記 procedure-arity-includes? 手続きも lib/gauche/procedure.scm にて定義。

(define (arity proc)
  (cond
   ((or (is-a? proc <procedure>) (is-a? proc <method>))
    (if (ref proc 'optional)
        (make <arity-at-least> :value (ref proc 'required))
        (ref proc 'required)))
   ((is-a? proc <generic>)
    (map arity (ref proc 'methods)))
   (else
    (errorf "cannot get arity of ~s" proc))))

(define (procedure-arity-includes? proc k)
  (let1 a (arity proc)
    (define (check a)
      (cond ((integer? a) (= a k))
            ((arity-at-least? a) (>= k (arity-at-least-value a)))
            (else (errorf "implementation error in (procedure-arity-includes? ~s ~s)" proc k))))
    (if (list? a)
        (any check a)
        (check a))))

とほほ。リキが無いッス。それにしても arity って何だろ。

何となく

イメージはできてるんですが、具体的なナニが微妙。あと @ の定義も微妙。昼間テンパッてるのが晩まで影響してます。(とほほ