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 って何だろ。
何となく
イメージはできてるんですが、具体的なナニが微妙。あと @ の定義も微妙。昼間テンパッてるのが晩まで影響してます。(とほほ