Computational Reflection . Class based Objectkented Languages

0 downloads 0 Views 935KB Size Report
domain where reflection can easily be implemented, because of the distributed nature of .... P.Maes has introduced a model of reflection based on ... is a subclass of OBJECT and an instance of itself and all metaclasses .... The following figure.
Computational. Reflection Class based Objectkented Languages JacquesFERBER LAFORIA Universite Paris 6, T 45-46 4 place Jussieu 75252 Paris Cedex 5 France Email: [email protected]

1

Abstract This paper describes various models of computational reflection in class based object oriented language. Two different approaches are covered: the meta-object approach which supposes that every object can have a meta-object describing and monitoring its behavior, and the message reification approach which describesa messageas an object. The me&object approach is discussed more fully showing that it is important to differentiate between structural reflection and computational reflection. We will see that, whereas classes and me&asses are very important for the former, they cannot cope adequately with the later. Therefore we introduce a model of computational reflection where me&objects are instances of a class META-OBJECT or of one of its subclasses. Permission to copy without fee all or part of this material is granted provided that the copies are not made or distributed for direct commercial advantage, the ACM copyright notice and the title of the publication and its date appear, and notice is given that copying is by permission of the Association for Computing Machinery. To copy otherwise, or to republish, requires a fee and/or specific permission. 0 1989 ACM 089791-333-7/89/0010/0317 $1.50

October 1-6, 1989

Introduction

After having been considered as a fascinating but rather sophisticated feature, reflection has become an important issue in the field of computing architecture and language design [Smith 821 Ferber 861 p.Maes 87.b] Ferber 881 [Watanabe & Yonezawa 881. Reflective systems have shown their practical interest for implementing systems, because of their ability to represent the system, i.e. its functionalities and its implementation, within the system itself. Some of the key features of such systems are their capacity for: -

implementation description: allocation of entities, garbage collection, incremental extension and re-implementation of the whole system;

-

monitoring entities of the language: inspection, analysis, and dynamic modification of the code within the language itself;

OOPSLA ‘89 Proceedings

317

-

interfacing and debugging: implementation of programming tools within the language;

-

self-reorganization: learning abilities of the system’sbehavior, for an increase in consistency and efficiency.

Object oriented languages (OOL) seem to be a major domain where reflection can easily be implemented, because of the distributed nature of data and procedure in objects. However there have been just a few works on that subject, leading to two different model of reflection: 1 the first model advocated by P.Cointe [Cointe 883, concerns the reflective use of classes and metaclasses for implementing objects. In a pure class model, like OBJVLISP [Briot & Cointe 871, each entity is an instance of a single class. Classes are instances of other classes, called metaclasses.This model allows for extension of the static part of OOL, i.e. the structural aspects of objects considered as implementation of abstract data types. 2 the second model, introduced by P.Maes [Maes 87.a], following Smiths work [Smith 821, is directed towards the use of computational reflection within the object oriented programming (OOP) paradigm. This model is based on the fact that each object has its own me&object that represents all its otherwise implicit informations: its structure and its way of handling messages.It has been shown that the use of meta-objects for buildind reflection in OOL allows for the definition of new features not initially present in the system: multi-inheritance, daemons on accessof attributes, interface programming, debugging tools, etc... [Maes 87.b] However, this model has been defined in the context of the language KRS [Van Marcke 881, which does not support the class/instance model of traditionnal OOL such as SMALLTALK, CL0s [Michiel & Gabriel] or OBJVLISP.

1.’

what is the nature of met&objects and/or of metacommunications, and what is their structure and behavior, ii’ how is the handling of messages and lookup of methods described at the meta-level related to basic messagepassing, iii’ when does the system uses meta-object and/or meta-communications. This paper introduces three models of computational reflection in class based object oriented languages. It shows that the so-called metackzsses which are very useful for structural reflection cannot deal correctly with computational reflection, i.e. they are not used at the computational meta level. The three models are: l

l

l

the metaclass model which is based on an equivalence between the meta-object and the class of an object. the specific metu-object model where meta-objects are instances of a class META-OBJECT or of one of its subclasses. the meta-communication model which is based on the reification of the message.

This paper describes the three models. All implementations are given in the OBJVLISP model of OOL. However, the implementation is not specific and can be adapted to any object oriented language using messagepassing as the basic control structure.

2

Aspects of reflection

When defining an reflective architecture, one has to answer three basic questions:

2.1

Domains and reflective

what entities should be reified, i.e. transformed into something which can be manipulated at the meta level? ii how is the causal link (i.e. the relationship between a lower and an upper level) implemented? ... 111 when does the system shifts up to a meta-level?

Creating a reflective architectures is a way of effectively relating the implicit entities of a computation domain Dn, called the basic level, into another computation domain Dn+I, called the meta-level. Each domain can serve both as a basic domain for an upper level, or as a meta-domain for a lower level, except the domain Do, made of referents, which can be used only as a basic level.

i

In the domain of object oriented languages, where the only entities are objects and messages,these questions can be reformulated as follows:

318

equations

Models of reflection can easily be defined by ways of reflection equations, which express how entities and expressions of the basic level, are described at the metalevel. Thus, reflective equations act as semantic equations, i.e. they give the semantics of the lower levels in terms of

OOPSLA ‘89 Proceedings

October 1-6, 1989

upper levels. For instance, in LISP, one can give the main reflection equation for expression evaluation: mge]pK

Dn= Ml[ (eval

'e B!l[pB

M [K])

1 Dn+l

where p and K represent respectively the environment and the continuation of the evaluation of the expression e, M is a semantic function from Dn to Dn+l, and where ‘e, is the data structure that representse. The traditional model of reflection is based on interpretation. The domain Dn is made of a set of entities and expressions, written in a language Ln, and of an interpreter In which interprets those expressions. The interpreter is written in a language Ln+l and is interpreted by an In+1 interpreter. When the system is not reflective, the language Ln+ I is radically different from Ln. For instance, if Ll is LISP, L2 could be a compiled language like C or Pascal, L3 the machine language instruction set, etc... In reflective architectures, there is a virtually infinite chain of identical languages Li, the so-called reflective tower. This can be achieved because there is one interpreter, call it I’, written in a language L’ different from Li, which is used to close the regression and replace the interpreter In at the highest level of computation needed. For instance, in 3-LISP [DesRivikes & Smith 841 , when the system encounters a reflective function at the level Dn, it shift up one level to Dn+l . There it starts a computation. If there is a call to a reflective function, it goes one level higher, at level Dn+2, etc... until it finds a reflective function which does not use any reflective functions. All non-reflective functions are interpreted by the interpreter I’, written in another language. Thus reflection can be implemented because there is no loop in the definition of reflective function. P.Maes has introduced a model of reflection based on representation of objects: each object 0 has a me&object M-O which represents 0 [Maes 871.This model is basedon an intensional semantics of reference in knowledge representation, which comes from the works of L.Steels [Steels 881: representation is a denotation process where concepts are implemented as conceptual objects. In this theory, every object is a representation of something, e.g. an entity of the “real” world (persons, computers, files,...), an event, a situation, etc... computing objects can also be represented by other objects, the so-called meta-objects. Objects are called the referents of their meta-objects.

October l-6, 1989

2.2

Reflection in Object oriented languages

In 3-KRS [Maes 87.a], when an object 0 receives a message, it delegates the messageto its me&object M-O. This process is applied again until the system finds a metaobject called DEFAULT-META-OBJECT,which usesa basic interpreter of messageswritten directly in LISP. However, 3-KRS is not a class based OOL. When adapting the 3-KRS style of reflection in the class/instance paradigm, one has to choose between different solutions: the metaobject can be either the receiver’s class, as in the structural model of reflection advocated by P.Cointe ICointe.871, or an instance of a specific class, META-OBJECT (or an instance of one of its subclasses). In chapter 4 the two models will be presentedand discussedin details. Using a meta-object for reflection is not the only way for implementing computational reflection: it is also possible to reify the communication process. This leads to a somehow different view of reflection in OOL, which can also be used for debugging and implementation purposes. In chapter 5, this model will be presented and compared to the preceding.

3

ObjVlisp: language

the demonstration

In order to develop the three basic reflection models in class based OOL, we will use OBJVLISP, a Ianguage whose organization is based on structural reflection [Cointe 871. Actually this language is not important in itself and will be used only for demonstration purposes. Many papers have introduced the OBJVLISP syntax. We will use this language using a blend of CLOS and Flavors syntax for readibility. The CLOS syntax will be used for the definition of classes, and the FLAVORS syntax for the definition of methods. For instance, the class SHIP will be described as: (defclass Ship (X-pos y-pos (:metaclass

(Object) x-vel y-vel) Class))

and the method DIRECTIONas: (defmethod (ship direction) y-vel x-vel) (atan

)

0

We will suppose that, for every slots (or instance variables) there is an accessmethod defined for it, as if the class was defined with the FLAVORSoptions :GE’lTABLE-INSTANCEVARIABLES and :SETTABLE-INSTANCE-VARIABLES.We are interested in reflection in the messagepassing style of

OOPSL.4 ‘89 Proceedings

319

programming, therefore we will use the standard syntax for messagepassing found in LISP basedOOLl: ::= (send



A-l

=

..)

Internal slots are accessed as simple variables (as in FLAVORS), and the generalized assignment function SETF is used for writing a value to a slot. Let us recall that the root of the OB IV LISP kernel is composed of two classes CLASS and OBJECT which are such that OBJECT is an instance of CLASS and that CLASS is a subclass of OBJECT and an instance of itself and all metaclassesare described as subclassesof the class CLASS:

Ml (send ret se1 al an) 1 W[ (send (meta-of rec.)"' :handleMsg ret se1 (list !@[a11 . . . . lE[anl))J

For all other expressions, the semantics is left to the basic language, here LISP. Implementing this approach asks for a choice regarding to the i and ii questions seen above: what is the nature of the meta-object, and when does the system shifts up to the meta-level? Answering to this will introduce a modification of the basic messagepassing primitive (defun send (obj se1 (apply (default-lookup obj part))

&rest

obj

args) sel)

where the DEFAULT-LOOKUP method is the basic primitive for accessing methods, and is implementation dependant. Answers to these questions will lead to two different models: 1 Use the class of the receiver as the meta-object, and go to the me&level when either the receiver or the receiver’s class wants to. However, our discussion about the different models of reflection is not language dependant. Every OOL which has access to the messagepassing primitive (i.e. SEND) could allow for refle&on, according to the models described here.

2 Use an instance of a specific class called METAOBJECT and go to the meta-level whenever the receiver has a related me&object.

4.1

4

Using meta-object reflection

for

As we have seen above, the first model of reflection was based on the me&object approach. In this model each object has a potential me&object associated to it which describes the basic behavior (i.e. the way objects handle messages)of the related object. We say that the meta-object represents the object, the latter being called the referentof the former rMaes.881. As meta-objects are objects themselves, they can also have meta-objects or their own. This model leads to a virtually infinite regression of metaobjects, transposing the infinite tower of 3-LISP into the realm of OOL. According to the me&object approach of reflection, the semantics of messagepassing can be defined by the sending of a specific message (called here HANDLEMSG) to the me&object:

Classes as meta-objects

In OOL based on the class/instance paradigm, the class of an object is usually considered as its meta-object, due to the natural structural reflection of the model. For instance, metaclasses are considered as meta-objects of classes becauseof their ability to define the structure of classes.In this model, the META-OF function is equivalent to the CLASS-OFfunction which returns the class of an object. Then the A- 1 equation above can be rewritten as follows: A-2

=

N[(send ret se1 al Elf (send (class-of rei;" :handleMsg ret se1 (list BIl[alJ . . . . g(l~anl))l

an) 1

The reflection equation says that it is equivalent, from a behavioral point of view, for an object 0 to receive a message M, or for its class to receive a message HANDLEMSG:

1 Unfortunately we cannot use the syntax of CLOS for messagesbecauseof its generic function approach.

320

OOPSLA ‘89 Proceedings

October l-6, 1989

M6taclass c-class

(defmethod (Class Lookup) (sel) ** takes the method :getmethod sel) ;br (send self **or try the superclass i$hen superclass :lookup superclass (send self

I

HandleMsg

0 M

se11 ))I

where GETMETHOD returns the method of a given selector and is implementation dependant.One can seefrom the code of the HANDLEMSG method that the method is assumedto be an object, i.e. an instance of the class METHOD.

The HANDLEMSG method is defined in the metaclassof C (here C-Class), Thus, the default handling method is described in the metaclass CLASS. When an object receives a message,it has to decide if it uses the standard interpreter, or rather go to the meta-level. This can be accomplished by a local slot defined in the receiver or in the receiver’s class (or in both). The first solution allows for the reflection of a simple object whereas the second sets all instances of a class into a reflection mode. Here is the definition of the messagepassing primitive using the first solution: send (ob j se1 . args) . . if the receiver is in reflection ;if (reflect? obj) to its class ;; send HandleMsg (send (class-of obj) :HandleMsg (make-instance Message :receiver obj :selector se1 :arguments args)) is the default interpreter ;: here built-in lookup ;; with (let ((m (default-lookup obj sel))) (if m (apply m (cons obj args)) (send obj :doesnotunderstand ret se1 args)))))) (defun

mode?

se1

args)

sel))

1

.* and apply it '\send meth :apply ret args) . . else error (LLnd ret :DoesNotUnderStand ret se1 args)))))

The next step is to define the methods LOOKUP and APPLY. The former is also defined in CLASS. It is a recursive definition of the basic lookup procedure found in the deep core of OOL (we supposea single inheritance scheme):

October 1-6, 1989

(defmethod (apply

(Method apply1 code ret args))

(ret

args)

In OOL based on virtual machines, like SMALLTALK, the definition of the APPLY method would manipulate the virtual machine, i.e. create a context, set arguments on the argument part of the context, sett the instruction pointer register with the beginning of the bytecode, and jump back to the interpreter. One should note that every modification in the interpretation of the meta-object implies a substitution or an alteration of the metaclass of the receiver’s class: as messagesare sent to the class of the receiver, methods like HANDLEMSG are defined in the class of the class, i.e. the metaclassof the receiver. Here are some of the consequences:

Notice, that we use a REFLECT? function. The use of messagepassing should be avoided here because it would lead to an infinite loop. The HANDLEMSG is defined in the class of the receiver. In order for every object to be able to use reflection, the HANDLEMSG method should be defined in the highest metaclass, i.e. CLASS (in OBJVLISP): (defmethod (Class HandleMsg) (ret ;; get method U;tm;:;eth (send self :lookup

As OBJVLISP is an object oriented language embedded in LISP, applying a method consists solely in applying its associated “compiled” function to the arguments. This definition is explicitely given in the APPLY method:

-

Every instances of a class share the same message interpreter. There is no possibility for particularizing the interpreter of a unique object.

-

Modification of the messageinterpreter can be done by substituting the metaclass: but this should be done with great care, because it can quickly lead to system inconsistency.

-

It is not possible to record personal characteristics of objects (e.g. statistical informations, history of incoming messages) in the meta-objectl. This limitation is very crucial, because, as we will see in the following section, one of the most important aspect of meta-objects is their ability for storing specific informations about their referent.

1 Except by using a dictionary where keys are instances of the class, and values are representation of instances. But then, this is very close to the following model where metaobject are instances of the class ETA-OBJECT.

OOPSLA ‘89 Proceedings

321

Therefore, using classesas me&objects does not allow for the monitoring of individual objects, and metaclasses are not “meta” in the computational sense, although they are “meta” in the structural sense.

4.2

:handleMsg ret se1 (list iE[alI . . . . iIB[anD))D (default-lookup ret sel) B!JI(apply ret (list iVl[alJ ..,. iI!I!Jan]))

The message HANDLEMSG is sent to the receiver’s own meta-object, as shown in the following figure:

Meta-objects as instances of the class Meta-Object

This model is a variation of the “meta-object approach”, But, instead of identifying the meta-object with the receiver’s class, meta-objects are defined as instances of a class called MET&OBJECT. Those me&objects differ from the class of the receiver. They include only operational and control informations about its referent, leaving the structural informations (i.e. the description of the internal structure of the receiver) to the receiver’s class. Then, if JOHN is an object, then (META-OF JOHN) = MJOHN, an instance of META-OBJECT. The following figure shows the general organization of classes, instances and me&objects.

The main distinction between this model and the previous one comes from the difference (in use and in implementation) of structural and computarional reflection: whereas in the former, classes are used both for structural description (definition of instance structure and of a set of applicable operations) and for computational description (how a messageis interpreted and a method is applied), this model split them apart, assigning each aspect to a different object: the class for the structural part, the me&t-object for the computational part. This model, which is the closest to the reflection scheme of 3-KRS, shows many advantages:

Each object can have its own meta-object: classes such as PERSON,OBJECT or CLASS (me&objects of OBJECTand CLASS have not been shown for clarity), meta-objects (MJOHN can have a meta-object called M-M-JOHN), and even META-OBJECT iself. The number of meta-objects is thus virtually infinite, and it is necessary to manage the creation of me&object in a “lazy” way, meta-object being created only when needed. The reflection equation of this scheme is A-l, given above, where META-OF returns an instance of META-OBJECTor of one ot its subclasses. BB[(send ret se1 al if (meta-of ret) M[(send (meta-of

A-l

322

. . . .

ret)

an)]

=

- the me&object of an object can easily be modified, - an object can be monitored by its meta-object, recording what is happening and eventually deciding of changes, - it is possible to define new ways of handling messagesby creating subclassesof META-OBJECT. In order to deal with meta-objects, changes should be accomplished in the kernel of the language. The first one consists in adding a specific slot, called META, to all objects. This can easily be done in modifying the definition of OBJECT. The second one is about the definition of the primitive messagepassing function, which checks if there is a meta-object bound to the receiver. It there is one, the message is delegated to the meta-object. Otherwise, the default messageinterpretation is used: (defun send (obj se1 . args) (let ((meta (meta-of obj))) is a meta-object ;; if there

OOPSLA‘89 Proceedings

October l-6, 1989

(if

meta *- delegate the message to it ;iend meta :HandleMsg (make-instance Message :sender self :receiver obj :selector se1 :arguments args)) .. standard processing '(;e:lTTð (default-lookup obj sel))) (if meth (apply meth obj args) (send obj :doesnotunderstand se1 args))))))

(let

(metaObjectClass) (make-instance metaObjectClass *ref self) )) (set (concat 'm- name) m) ;; makes it the meta-object (setf meta m) self))

((m

Suppose that a class PERSONand two instances, JOHN and MARY, have been defined: (defclass (age)

In writing this function, one should take care in accessing the slots META and CLASS. These should not be done by message passing for avoiding an infinite loop in the regression of reflection. Here is a possible definition of the META-OBJECT class, whose instances can record the number of incoming messagesof their referent, i.e. their basic object: (defclass Meta-Object (Object) ((referent) .* the related object (nbMsg :initform'b));; number of messages by the referent ) ;; received

and its methods: ;;

the message handler which interprets messages i; (defmethod (Meta-Object HandleMsg) (msq) (let* ((se1 (send msg :selector)) (args (send msg :arguments)) (ret (send :receiver))) (format t "Meta message: -S : -S '1 ret sel) the messages ;; counts (setf nbMsg (l+ nbMsg)) ** takes the method ' ilet ((meth (send self 'lookup iclass-of ret) sel))) ,* and apply it iif meth (send m :apply ret arqs) (send ret :DoesNotUnderStand se1 args) ) ) ) )

Here the LOOKUP method is not defined in the receiver’s class, but in the meta-object: of methods in the ;; finding receiver's class ;; . . and its superclasses ;defmethod (MetaObject Lookup) (obj sel) if the object is not nil (when obj ** takes the method i;r (send obj :qetmethod sel) . . or recurse on the superclass \kend self :lookup (send obj :superClass) sell 1) ) ) 1

Here is a method, defined in OBJECT which creates and binds a meta-object to an object, given the class METAOBJECTor one of its subclasses: create idefmethod .

9

a meta-ob (object

Odober 1-6, 1989

ject from makemeta)

a SModel

Personne 1

(defmethod (Person (>= age 18)) (setq

John

(setq

Mary

(object) adult?)

(make-instance : sex (make-instance : sex

0

Personne 'Male :age 35)) Person 'Female :age 24))

In a standard execution, when JOHN and MARY do not have any met&object, there is no shift to the me&level (send = 35

John

:adult?)

and the display of the object JOHN shows that there is no me&object associatedto it. ---_---__--___--__------------------------of : # ;;; display ------------_-----------------------------#ca I class : I meta : 0 35 I age :

class

: person>

It is possible to create a meta-object and to bind it to JOHN by sending the messageMAKEMETA: (send

Toto

:makemeta

Meta-Object)

The object JOHN is now monitored by its meta-object, called M-JOHN, instance of META-OBJECT. For instance if we ask if JOHN is an adult, (==> John :adult?) Meta message: #


: adult?

we obtain the same result, but the system has gone up to the meta-level. Here is the structure of M-JOHN: ------------------------------------------of : #
------------------------------------------I class : : meta-object> # I messages : #< a message : adult?>)

It is possible to execute a recorded message,using a method DOITAGAIN which usesthe standardHANDLEMSGmethod: ;;

re-execute ;; without (defmethod (let

the nth most recent message memorizing it (History-Meta-Object DoItAgain) (n) ((msg (nth n history))) (when msg (format t "Re-execute -S : -S" referent msg) (send super :HandleMsg msg) )))

The message ‘adult?’ can be sent again, using its index in the history list:

324

Here, instead of being related to the receiver’s state, the system shifts up for all message passing, except when it receives a SEND message, in order to avoid loops due to infinite regression. Then the system is (nearly) always in a reflection mode. It is easy to add new communication types by creating subclassesof the class MESSAGE, and passing them as an argument of the SEND primitive. For instance, in a

OOPSLA ‘89 Pmxedings

October l-6, 1989

distributed system where messages are remotely sent to objects situated in different processors, there is a need for a “remote send”. This can be done by passing a specific class REMOTEMESSAGEas an argument of the function SEND. Here is the definition of the SEND primitive in this model: (defun

send

&keys selector arguments messageclass) (if (eq selector 'send) standard processing ;;; (let ((meth (default-lookup obj sel))) (if meth (apply meth obj args) ss else go to meta ibend (make-instance (or messageclass Message) :sender self :receiver obj :selector selector :arguments arguments) :send)))

John

receiver

:DoesNotUnderStand self)))))

There is no infinite regression if we suppose that there is at least one meta-... meta-object which does not have a metaobject.

(obj

Then, sending a remote messageADULT? to an object JOHN can be done as follows: (send

(send

:selector :messageClass

:adult?

RemoteMessage)

Compared to the preceding models, this one has the following advantages: - It is easy to differentiate between several types of messages: subclasses of communication can be defined and used instead of the standard MESSAGE class. - The use of different types of messages allows an incremental extensions of the possible use of the system. Addition of notion such as concurrent message passing, continuation, etc... can easily be incorporated. However, the main disadvantage of this model is that it does not say anything on objects: it is impossible to monitor objects, to represent specific informations about receivers, or to represent the behavior of a single object. It should be noted that this model can be used in conjunction with the “met&object” models. For instance, here is a modified version of the SEND method defined in the class MESSAGE which permits the use of meta-objects as instances of the class META-OBJECT (or one of its subclasses): (defmethod (Message send) () is a meta-object ;; if there (if (meta-of receiver) the message to it :: delegate (send (meta-of receiver) :HandleMsg self) (let* ((meth (send (class-of receiver) :lookup selector))) (if meth (send meth :apply receiver arguments)

October l-6, 1989

6

Conclusion

We have covered several models of computational reflection for object oriented languages with classes, and have discussed the consequencesof thesesmodels. We have seen that metaclassesare not a good candidate as me&objects for computational reflection. Then it is important to distinguish between structural reflection, where metaclasses are very helpful, and computational reflection, where a specific class, called META-OBJECT, should be introduced as the root class of all meta-objects. Messages also can be reified by allowing them to be instances of a class MESSAGES.In SMALLTALK, the class MESSAGEis only used for debugging purposes, whereaswe have used them for all messagepassing. There is only one messagewhich should not go to meta: the SEND message sent to an instance of the class MESSAGE. Then we have seen that reflection by meta-objects, and reflection by messagereification can be used altogether.

7

Aknowledgment

I would express my gratitude to J.P.Briot, whose critical comments about the necessity to clarify many of the ideas discussed here have been the starting point of that paper. I also benefitted from the encouragements and discussions of P.Cointe and J.F Perrot.

References [Agha 861 G. Agha, “Actors - A Model of Concurrent Computation for Distributed Systems,” MIT Press, 1986. [Briot & Cointe 871 J-P. Briot and P. Cointe, “A Uniform Model for Object-Oriented Languages Using the Class Abstraction,” IJCAI’87, Milano, Italy, August 1987. [Cointe.87] P. Cointe “Me&lasses are first class objects: the OBJVLISP model”, OOPSLA’87 Orlando, USA, October 87.

OOPSLA ‘89 Proceedings

325

[Cointe 881 P. Cointe “A Tutorial Introduction to Metaclass Architecture as provided by Class Oriented Languages”, Fifth Generation Computer Systems 88, Tokyo, Japan, November 1988. [De&vi&es 8~ Smith 841 J.C. DesRivieres, B.C. Smith, “The Implementation of Procedurally Reflective Languages”, ACM conference of the third ACM Lisp and Functional Programming, Austin, USA, July 1984. [DAI $71 “Distributed Artificial Intelligence,” edited by M. N. Huhns, Pitman - Morgan Kaufman, 1987.

[Smith 821 B.C. Smith, “Reflection and Semantics in a Prdurd Language,” PhD Thesis, TR 272, M.I.T., USA, 1982. [Van Marka gg] K. Van Marke, “the Use and Implementation of the Representation Language KRS” PhD thesis, Vrije Universiteit Brussel, April 8% Dyatanabc C Yowzawa tl] T, Watanabeand A. Yonezawa, “Reflection in an Object-Ortid Concurrent Language,” OOPSLA%3 draft, ‘ITT, Tokyo, Japan, April 1988.

[Ferber 841 J. Ferber, “Mering: An Open-Ended object oriated &tguage for knowledge representation” ECAI’84, Italy, September 1984. [Ferber 863 J.Ferber, “Towards a Reflective Actor Language”, ECAI 86, Brighton, Great Britain, July 1986. [Ferber 881 J. Ferber, “Conceptual Reflection and Actor Languages,” in [Reflection 881.

[Ferber & Briot 883 J.Ferber & J.P. Briot “Design of a Concurrent Language for Distributed Artificial Intelligence” Fifth Generation Computer Systems 88, Tokyo, Japan, November 1988. [Maes 87.a] P. Maes, “Concepts and Experiments in Computational Reflection,” OOPSLA’87, Sigplan Notices, Vol. 22 N’12, December 1987. [b&s 87.b] P.Maes “Computational Reflection” PhD thesis. Vrije Universiteit Brussel, 1987, also Technical Report 87-2. [Maes 881 P. Maes, “Issues in Computational Reflection,” in [Reflection 881. [OOCP 871 “Object Oriented Concurrent Programming,” edited by A. Yonezawa and M. Tokoro, MIT Press, 1987. [Pitrat 851 J.Pitrat “Maciste ou comment utiliser un ordinateur sans &ire de programme. Colloque Intelligence Artificielle de Toulouse, Research Report LAFORIA n”58, 19815. [Reflection 881 “Me&Level Architectures and Reflection,” edited by P. Maes and D. Nardi, North Holland, 1988. [Steels 881L.Steels “Meaning in knowledge representation” in [Reflection 881.

326

OOPSLA ‘89 Promdngs

October 1-6, 1989