Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. •...

36
Reflection Suzuki Tomohiro 20101221日火曜日

Transcript of Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. •...

Page 1: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

ReflectionSuzuki Tomohiro

2010年12月21日火曜日

Page 2: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

import java.lang.reflect;...final Method[] methods = someClass.getDeclaredMethods();

gosh> (define-syntax double (syntax-rules () ((_ x) (+ x x))))gosh> (double (begin (display "hello") 2))hellohello4

[meta [meta subject]] <== [:add-script ‘(=> :begin ...

Type t = typeof(SomeClass);

ConstructorInfo ci = t.GetConstructor(new Type[0]);

ClassA ca = (ClassA)ci.Invoke(new Object[0]);

def actor := reflectOnActor();def oldmirror := actor.becomeMirroredBy: (extend: actor with: { def send(msg) { log(msg);...

>>> dir([1,2,3])['__add__', '__class__', ... 'insert', ..., 'pop', ... ]

Reflection?loadClass(String name) {

CtClass c = new CtClass(name);

c.addMethod(printM, new ClassMap());

return resolveClass(defineClass(c.toByteCode()));

}

2010年12月21日火曜日

Page 3: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

今日はReflectionを言語のコアとして持つ次の3

つの言語の特徴と概念・利用例を説明します

• 3-Lisp (Procedural Reflection [Smith, 83])

• 3-KRS (Reflection for OO-languages [Maes, 87])

• ABCL/R (Reflection for concurrent languages [Watanabe, Yonezawa, 88])

“A reflective system is a system which incorporates structures representing (aspects of ) itself ” [Maes, 87]

2010年12月21日火曜日

Page 4: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

• Procedural ReflectionLispにReflectionを導入した3-Lispを紹介.Proceduralというのがついているのはlogic-basedやrule-basedな言語と区別するためだと思われる.

• 3-LispはReflectionの草分け的存在

• 3-Lispは2-Lispというものを使って実装.

• 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.higher-orderであり関数のdesignatorである “closure”を導入

• 1-Lispは既存のLisp処理系と2-Lispと比較するために用意されたschemeに似た言語

“Reflection and Semantics in Lisp” [Smith, 83]

2010年12月21日火曜日

Page 5: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

3-Lispの普通の計算“X => Y” means X normalizes to Y

• (+ 1 2) => 3

• ((LAMBDA SIMPLE [X] (* X X)) 4) => 16

• ‘A => ‘A

(lambda simple ...)というのはreflectiveではないfunctionを表している.

後のスライドで(lambda reflect ..) というreflective functionが現れる

handleと呼ばれるこの形のtermは “一つ下のレベル”のdomainを表す.

例えば, level 0 のプロセッサで3を表現する場合のlevel 1のプロセッサのデータ構造は’3である

(NORMALIZE ‘(+ 2 3)) designates the normal-form structure to which (+ 2 3) normalizes and therefore returns the handle ‘5

2010年12月21日火曜日

Page 6: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

Domain

• A computational system answers questions of some domain(s). In this case, the system is for the domain.

• A reflective system’s domain is itself.

System:struct car{ wheel ... speed ...};car C1, C2, C3;

System

2010年12月21日火曜日

Page 7: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

Infinite Tower

• 無限なMeta Circular ProcessorのTowerを想定

• reflective functionは一つ上の場所で実行される関数SchemeでSchemeインタプリタを作成した人は少なくないのでは??

環境, 実行コード, 数字やリストを表すデータ構造

(let ((a 3)) (+ 2 a))

2010年12月21日火曜日

Page 8: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

3-Lispのreflectiveなコード例

• reflective functionは(lambda reflect ...)で作れる

• その関数は引数に必ず環境(env)と継続(cont)をとる

• 一つ上のプロセッサからなら今の場所の環境や継続が手に入る継続,環境はLispのリストで表現されているので, Lispで処理が可能

• 例えば上の‘3というのは一つ上のプロセッサで下のプロセッサ内の3を表現する方法を表している

(+ 11 (three)) は 14 にnormalize※される

※Normalizeというのは3-Lispにとってのeval2010年12月21日火曜日

Page 9: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

Vantage Point• System自体にどうアクセスするか

• gdbのようにアセンブリレベルでstepして見るは細かすぎる

• どのようにSystemを“抽象化”してプログラムから触れるようにするか

• 3-Lispではそのときの環境, 継続※にアクセスできるようにした.

※継続(continuation): とある計算のあとに実行される手続きのこと.

SICP(紫本)に継続を使ったインタプリタの例があります.

2010年12月21日火曜日

Page 10: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

(LET [[x 3]] (BOUND X)) は $ T にnormalize※される

※Normalizeというのは3-Lispにとってのeval

コード例: BOUND

2010年12月21日火曜日

Page 11: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

• コード例: QUIT

• 継続を実行しない reflective

functionなので現在のレベルを止めて一つ上のレベルに移る

read-normalize-printは入力を読み取った式を指定されたレベルで実行するインタプリタ

2010年12月21日火曜日

Page 12: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

Implementation

• infinite towerを実装するには?

• プロセッサのstate(これはreflective functionから見えない)を使ってreflective functionの必要に応じてtower

を上がるようにする(lazyに実装)

• あまりよくわかっていません...

“The Implementation of Procedurally Reflective Languages” [J. Rivières and B. C. Smith, 1984]

2010年12月21日火曜日

Page 13: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

• Reflectionはprocedure-based [Smith, 82]やlogic-based

[Weyhrauch, 80], rule-based [Davis, 82]に適用されてきた.

• この論文ではReflectionをObject-Oriented Langauge

に導入した3-KRSという言語の機能を紹介

“Concepts and Experiments in Computational Reflection” [Maes, 87]

2010年12月21日火曜日

Page 14: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

Reflectionの定義

• “We define computational reflection to be the behavior exhibited by a reflective system, where a reflective system is a computational system which is about itself in a causally connected way”

2010年12月21日火曜日

Page 15: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

Causal Connection(i) The system always has an accurate representation

of itself

(ii)The status and computation of the system are always in compliance with this representation. This means that a reflective system can actually bring modifications to itself by virtue of its own computation.

※Maesさんの論文で初めて出た概念ではない

System

例 list of methods [A, B]

list of methods [A, B, C]

1. メソッド一覧を取得

その内容を変更

2. 変更はsystemに反映

2010年12月21日火曜日

Page 16: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

3-KRS• KRS[Steels, 86]にReflectionを導入

• 次のような概念/特徴を持つ

• Meta-Objects: objectsのふるまいを司る

• Uniform: meta-objectsを含めすべてobjects

• Consistent: objectsは実際にmeta-objectsによって実装されている

• Dynamic: meta-objectsのrelationはruntimeに変更できる

New!

2010年12月21日火曜日

Page 17: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

Meta-Objects

• Objects for an object and that have methods for

• how the (referent) object invokes a method

• how the object is printed

• how its instance is created

• Meta-Objects自体もobjectsなので, meta-objectsはlazyに作られなければならない.

2010年12月21日火曜日

Page 18: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

利用例 :

Tracer

• 本来のMethodが呼ばれる際に何をprint

するようなmeta-object.

• intercessionとして動く例

traceされるobject

traceするmeta-object 普段と違う

Eval-method

2010年12月21日火曜日

Page 19: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

Clear Separation

• 普通のobjectsは対象のdomainのモデルであるべき

• なのでString representationなどは普通のobjectsは備えるべきではない悪い例: JavaのtoStringメソッド

• 明示的にmetaな世界とを分けるべき.悪い例: Pythonのobj.__class__ というconvention(のようにmeta-objectsを関連づける)

2010年12月21日火曜日

Page 20: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

4 Properties4種類のReflection

• introspectione.g. メソッド一覧を取り出す

• self-modificatione.g. メソッドを付け加える

• invocatione.g. 取り出したメソッドを実行する

• intercessione.g. 本来実行されることの前後にコードを挿入する

“Computational Reflections” [Maes, 87]

2010年12月21日火曜日

Page 21: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

• Concurrent Programming LanguageであるABCL/1

にReflectionを導入したABCL/Rの紹介

• Concurrenct Programmingで生じる問題(Time

Warpなど)をReflectionを用いて解決できる

“Reflection in an Object-Oriented Concurrent Language” [Watanabe, Yonezawa, 88]

2010年12月21日火曜日

Page 22: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

(Concurrent) Objects in ABCL/REach object has

• individual computation power

• local persistent memoryインスタンス変数のようなイメージ

• message queue

• actions (or scripts, methods)

• read/write local state• create new objects• sending messages to objects• symbolic/numerical operations

2010年12月21日火曜日

Page 23: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

2010年12月21日火曜日

Page 24: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

1. Arrival

2. Receiving

3. Acceptance

4. End of Processing a Message

Message TransmissionMessage

objectmsg msg

- Past Type Message [Target <= Message] でTargetにMessageを非同期で送信. Targetの処理を待たない

- Now Type Message [Target <== Message] でTargetにMessageを送信. Targetの処理が終わるのを待つ

2010年12月21日火曜日

Page 25: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

Meta-Objectsin ABCL/R

← Receiving

← Acceptance

← End of Processing a Message

← queue← state

← scriptset← evaluator← mode

対応するscript

があれば実行

2010年12月21日火曜日

Page 26: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

Meta-Objectsの利用

• [meta x]にアクセスし,そのオブジェクトのメソッドを改造したり,implicitな状態(queueなど)を取得する

• 前の3つの関数(message, begin, end)をカスタマイズし,対象のobjectのmeta-objectとする[meta [meta x]] <= [:add-script ‘(=> :begin ...とするとxのmeta-objectのbegin関数を書き換えられる

2010年12月21日火曜日

Page 27: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

利用例:

Manager&

Workers

• WorkersはjobをConcurrentに処理をする

• Managerはadd-script※で動的にWorkerにscriptを加える

※meta-objectsはadd-script, script, delete-script, stateというメッセージをデフォルトで受け取る2010年12月21日火曜日

Page 28: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

利用例:

Monitor

対応するscript

があれば:has-accepted

をMonitorに送ってあとは通常どおり実行

2010年12月21日火曜日

Page 29: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

Time Warp

• Concurrent Systemはグローバルな時計を前提とできない

• 時間がずれて届いたメッセージを検知したら巻き戻す(Rollback)するシステム

• :anti-messageはそのメッセージによってobjectにもたらされる効果を巻き戻す

• コードはAppendix参照

msgA at: 2msgB at: 4msgC at: 5msgD at: 3

objectok,ok,ok,...?

messages arrive

atはメッセージが生成された時間を表す

2010年12月21日火曜日

Page 30: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

object B

object Cobject A

msgA at: 2

msgB at: 4msgC at: 5

object D

Time Warpをいれてmeta-objectは様々なobjectに対して使うことができる.

-> modularity

2010年12月21日火曜日

Page 31: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

object B

object Cobject A

msgA at: 2

msgB at: 4msgC at: 5

object DmsgD at: 3

object Dの時計は他のobjectと合っていない!

-> object Bが他のobjectにanti-messageを送ってrollback

Time Warpをいれてmeta-objectは様々なobjectに対して使うことができる.

-> modularity

2010年12月21日火曜日

Page 32: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

object B

object Cobject A

msgA at: 2

msgB at: 4msgC at: 5

object DmsgD at: 3

anti-message of: 3

anti-message of: 3

object Dの時計は他のobjectと合っていない!

-> object Bが他のobjectにanti-messageを送ってrollback

Time Warpをいれてmeta-objectは様々なobjectに対して使うことができる.

-> modularity

2010年12月21日火曜日

Page 33: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

Summary

• Reflectionの研究流れを説明した• Procedural, Object-Oriented, Concurrent

• Reflectionに現れる概念を説明した• domain, causal connection, vantage point

• Reflectionを使うことでmodularityを高めつつ複雑なものを表現することができる例を示した

2010年12月21日火曜日

Page 34: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

Javassist [Chiba 2000]

• JavaのReflectionはintrospectionしか提供していなく,他のReflection

の拡張はJVMを改造したりJavaのbyte-codeの知識が必要. hookを挿入するだけのbehavioral reflectionではなく実際にクラスのメモリ内構造を変更するstructural reflectionを提供するJavassistを紹介.

• Javassistはクラスのロード時メソッドを置き換えるためのprogrammer- friendlyなAPIを提供する.

CtClass c = new CtClass(name);/* 様々なCtClassのAPIを実行 */

c.toByteCode;

2010年12月21日火曜日

Page 35: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

def Point := object: { def x := 0; def y := 0; def distanceToOrigin() { (x*x + y*y).sqrt };};def p := Point.new(2,3);// request a mirror on p via the mirror factory> def mirrorOnP := reflect: p;>><mirror on:<object:2493837>{x,x:=,...}>

>mirrorOnP.listSlots().map: {|slot| slot.name };>>[super, super:=, x, x:=, y, y:=, distanceToOrigin]// let's add a z coordinate to our point

def [zaccessor, zmutator] := lobby.at.lang.values.createFieldSlot(`z,0);// we only add the accessor, so the slot is read-only>mirrorOnP.addSlot(zaccessor);> p.z>> 0// we can also read slots reflectively:> def x :=mirrorOnP.grabSlot(`x)>> <accessor method for:x>// and we can also invoke methods reflectively:>mirrorOnP.invoke(p,lobby.at.lang.values.createInvocation(`distanceToOrigin,[],[]));>> 3.605551275463989// finally, we can remove slots...> mirrorOnP.removeSlot(`z);

AmbientTalk’s reflection

“Mirror-based reflection in AmbientTalk”, [Mostinckx et. al., 2008]

2010年12月21日火曜日

Page 36: Reflection - 東京大学 · • 3-Lispは2-Lispというものを使って実装. • 2-LispはLispを処理するために作られた言語. evalではなくnormalizeと呼ぶ.

AmbientTalk tutorialよりhttp://soft.vub.ac.be/amop/at/tutorial/reflection

2010年12月21日火曜日