meta-objective lisp @名古屋 reject 会議

20
Meta-objective Lisp @dico_leque 2011/02/26 NagoyaRejectKaigi

Upload: dicoleque

Post on 11-Nov-2014

2.094 views

Category:

Technology


4 download

DESCRIPTION

 

TRANSCRIPT

Page 1: Meta-objective Lisp @名古屋 Reject 会議

Meta-objective Lisp

@dico_leque2011/02/26 NagoyaRejectKaigi

Page 2: Meta-objective Lisp @名古屋 Reject 会議

概要

n Common Lisp Object System 系の Metaobject

Protocol について説明

n 説明に使うのは Gauche Scheme interpreter のオブジェクトシステム

Page 3: Meta-objective Lisp @名古屋 Reject 会議

Lisp はオブジェクト指向言語n CLOS -- Common Lisp Object System

n 「しーろす」または「くろす」と読む

n ISLISP Object System -- ILOS というのもある

n Ruby にも色々影響を与えている

n ANSI Common Lisp 制定当時にあった Lisp 用オブジェクトシステムの上位互換を目指した柔軟性

Page 4: Meta-objective Lisp @名古屋 Reject 会議

速習 CLOS (1)

n クラスにはスロット(インスタンス変数)がある

n (define-class <foo> () ((slot1) (slot2)))

n 多重継承できる

n (define-class <baz> (<foo> <bar>) ())

Page 5: Meta-objective Lisp @名古屋 Reject 会議

速習 CLOS (2)n メソッドはクラスではなく総称関数(generic-

function)に属する

n 引数に応じて最も特定度の高いメソッドが呼ばれる(define-generic foo)(define-method foo ((x <sequence>) (y <sequence>)) 0)(define-method foo ((x <sequence>) (y <string>)) 1)(define-method foo ((x <string>) (y <sequence>)) 2)(define-method foo ((x <string>) (y <string>)) 3)

(foo '() '()) ; => 0(foo '() "a") ; => 1(foo "a" '#()) ; => 2(foo "a" "b") ; => 3

Page 6: Meta-objective Lisp @名古屋 Reject 会議

速習 CLOS (3)

n CLOS 自体も CLOS で書かれている

n メソッドの適用順の決定、インスタンス生成も総称関数として定義されている

n ユーザーは必要に応じて、通常の動作をオーバーライドできる

Page 7: Meta-objective Lisp @名古屋 Reject 会議

MOP

n Metaobject Protocol

n introspection: オブジェクトの内部表現にアクセスするための API

n intercessory: オブジェクトシステムの動作を変更するための API

n 今回は intercessory の話をします

Page 8: Meta-objective Lisp @名古屋 Reject 会議

Metaobjects

n オブジェクトの振る舞いを記述するオブジェクト

n <class> <generic> <method>

n オブジェクトシステムのデフォルトの振る舞いは

(make <class>) (apply-generic-function <generic>) といったメソッドで記述されている

Page 9: Meta-objective Lisp @名古屋 Reject 会議

例 (1) シングルトンパターン

n クラスのインスタンス生成をカスタマイズ

n <singleton-meta> クラスのインスタンスであるクラスは make すると常に同一のインスタンスが返る

n (instance-of <クラス>) でもインスタンスを取り出せる

n singleton なクラスのサブクラスも singleton になる

Page 10: Meta-objective Lisp @名古屋 Reject 会議

例 (1) シングルトンパターン(define-class <singleton-meta> (<class>) (%the-singleton-instance) )

(define-method make ((class <singleton-meta>) . initargs) ...)

(define-method instance-of ((class <singleton-meta>) . initargs) (apply make class initargs))

(define-class <singleton-mixin> () () :metaclass <singleton-meta>)

from gauche/lib/gauche/mop/singleton.scm

Page 11: Meta-objective Lisp @名古屋 Reject 会議

例 (2) O/R マッパー

n DB のカラムに対応するスロットを持つクラス

n <orm> をメタクラスとするクラスは、 DB アクセスによりスロット名が決定される

Page 12: Meta-objective Lisp @名古屋 Reject 会議

例 (2) O/R マッパー(define-class <orm> (<class>) ())

(define-method compute-slots ((cl <orm>)) (let ((super-slots (next-method))) (lset-union (lambda (x y) (eq? (car x) (car y))) (map (lambda (name) `(,name :init-keyword ,(make-keyword name) :accessor ,(string->symbol (format "~A-of" name)))) (load-slot-names cl)) super-slots)))

(define-class <foo> () () :metaclass <orm>)

※ load-slot-names は適当に定義する

Page 13: Meta-objective Lisp @名古屋 Reject 会議

例 (3) 特異クラスn Ruby の特異クラス風のメソッドディスパッチ

n ある値と等しい値を表すクラス

n (eql 0) を評価すると 0 だけをインスタンスとするクラスが返る

n <generic> のサブクラスを作り、 (eql x) をもっとも特定度の高い特定化子として扱う

Page 14: Meta-objective Lisp @名古屋 Reject 会議

例 (3) 特異クラス

(define-generic fact :class <eql-specializable-generic>)

(define-method fact ((n (eql 0))) 1)

(define-method fact ((n <integer>)) (* n (fact (- n 1))))

Page 15: Meta-objective Lisp @名古屋 Reject 会議

例 (3) 特異クラス(define-class <eql-specializer> (<class>) ((object :getter eql-specializer-object :init-keyword :eql-specializer-object)))

(define (eql obj) (make <eql-specializer> :eql-specializer-object obj))

(define-class <eql-specializable-generic> (<generic>) ())

(define-method compute-applicable-methods ((gf <eql-specializable-generic>) args) ...)

(define-method sort-applicable-methods ((gf <eql-specializable-generic>) methods args) ...)

※実際のコードは60行程度 http://d.hatena.ne.jp/leque/20110105/p1

Page 16: Meta-objective Lisp @名古屋 Reject 会議

CLOS / MOP で他にできること

n スロット(インスタンス変数)アクセスのカスタマイズ

n スロットの読み書きが DB アクセスになるようなクラス

n 他のオブジェクトに委譲するスロット

n validator 付きスロット

Page 17: Meta-objective Lisp @名古屋 Reject 会議

n メソッド適用規則のカスタマイズ

n クラス以外でディスパッチするメソッド Pascal Costanza, Charlotte Herzeel, Jorge Vallejos, Theo D’Hondt: “Filtered dispatch”, Proceedings of the 2008 symposium on Dynamic languages

n メソッドコンビネーション

n アスペクト指向風の before, after, around

n 適用可能なメソッドの戻り値を組み合わせる

CLOS / MOP で他にできること

Page 18: Meta-objective Lisp @名古屋 Reject 会議

n チューニング

n メソッドキャッシュの自作

n lazy initialization 等々

n 汎用オブジェクトシステムの作者よりもアプリケーション作者の方が今扱っている問題をよくわかっているはず

CLOS / MOP で他にできること

Page 19: Meta-objective Lisp @名古屋 Reject 会議

DSL と MOP

n DSL の対象 Domain によっては、言語の提供するオブジェクトシステムが合わない場合もある

n 既存の仕組みで頑張ってもよいけど、根本から変えた方がよい場合もある

Page 20: Meta-objective Lisp @名古屋 Reject 会議

まとめ

n Lisper にとってはオブジェクトシステムもただの

DSL

n CLOS MOP はオブジェクトシステムを書くためのフレームワーク