Reflective Facilities in Smalltalk-

Brian Foote Ralph E. Johnson

Dept. of University of Illinois at Urbana-Champaign 1304 W. Springfield Urbana, IL 61801

[email protected] (217) 333-3411 [email protected] (217) X4-0093

Abstract Monitors, atomic objects, and distributed objects present similar difficulties. These applications all require that an Computational reflection makes it easy to solve problems object be able to intercept any messagesent to it on a per- that are otherwise difficult to addressin Smalltalk-80, such object rather than a per method-basis. In Smalltalk-80, the as the construction of monitors, distributed objects, and method dispatch mechanism is buried within the Virtual futures, and can allow experimentation with new Machine, beyond the programmer’s grasp. inheritance, delegation, and protection schemes. FulI reflection is expensive to implement. However, the ability Recent work on object-oriented computational reflection to override method lookup can bring much of the power of /$faes 1987h] has provided a general framework for reflection to languages like Smalltalk- at IXJ cost in addressing problems like those discussed above. Reflection efficiency. is intriguing because it seemsto allow programmers to make open-ended,localized extensions to the languagesand Introduction systems with which they are working. Reflective systems are f?equently constructed using One of the attractions of object-oriented languages is their metacircular interpreters, This approach provides the extensibility. Programmers gain confidence that facilities highest possible degree of flexibility at the expense of that are not already available in a given environment can performance, We believe that full reflection may not be easily be constructed. Current systems make it easy to necessary to addressmany of the kinds of problems that define data types like complex or arbitrary precision have attracted so much attention to it. For this reason, we numbers. New object types become as “first class” as those have focused on how a handful of reflective facilities can built into the language. A big part of the appeal of object- efficientlv bring much of the Rower of full reflection to oriented programming is that programmers believe that, if Smalltalk-80. In particular, this paper discussesredefining they really wanted to, they could redefine the world. the default method lookup mechanism, and looks at how lightweight classescan be used to implement . However, there are a few kinds of objects that are difficult to implement in conventional object-oriented programming languages such as Smalltalk- [Goldberg 19831and C++ Reflection [Stroustrup 19861. For example, a future object [Halstead 19851acts as a surrogate for a result that is in the A reflective program is one that reasons about itself. A of being computed. Messagesto the future cause the sender fully reflective procedural architecture [Smith 19831is one to wait until the result is computed, at which time the in which a process can accessand manipulate a full, messageis relayed to the result. Object-oriented languages explicit, causally connected representation of its own state. make it easy to redefine simple methods, but futures must “Causally connected” means that any changes made to a intercept any messagesent them. process’sself-representation are immediately reflected in its actual state and behavior.

Permission to copy without fee all or part of this material is granted provided waes 1987a] [Maes 1987b] describes an object-oriented that the copies are not made or distributed for direct commercial advantage, reflective language called 3XRS. 3-KRS partitions every the ACM copyright notice and the title of the publication and its date appear, object into a domain specific referent and a reflective and notice is given that copying is by permission of the Association for m&object. The referent contains information describing Computing Machinery. To copy otherwise, or to republish, requires a fee and/or specific permission. the real-world entity that the object represents. The 0 1989 ACM 089791-333-7/89/0010/0327 $1.50 contains information describing its referent as a

October l-6, 1989 OOPSLA ‘89 Proceedings 327 computational entity in itself. Enforcing this separation Lisp Based Systems encouragesthe emergenceof standardprotocols for communicating between objects and metaobjects. The The Common Lisp Object System (CLOS) [Bobrow 19881 distribution of the system’s self-representation among the [Keene 19891is a marriage of Common Loops and New system’smetaobjects makes this self-representation easier Flavors that provides a very powerful generic function-based to think about and manipulate. method combination mechanism. The CLOS Metaobject Protocol provides a metacircular definition of the entire Manipulation of an object’s metaobject can affect the way CLOS system. The MOP is intended to permit open-ended in which computation for its referent object is carried out. experimentation with new object-oriented programming For instance, in 3-KRS, an object can have method lookup paradigms, and has been used to successfully implement a redefined by giving it a new metaobject that defined a number of distinctly un-CLOS-like object-oriented “deviating” interpreter. Such changes can be made on a per- programming systems. The MOP is designed to permit the object basis, since each object has its own metaobject. modification of basic language mechanisms such as method Specialized metaobjects can be introduced dynamically. The lookup from with CLOS itself. ability to introduce temporary, localized changes to an object’s semantics without changing the object itself The mechanismsprovided in CLOS’s standard method accounts for a great deal of reflection’s power. combination scheme are quite powerful. CLOS generic functions can specialize on any of their arguments, not just Maes distinguishes between systems with reflective the first, and may specialize on instances as well as classes facilities and full-fledged reflective architectures. and types. The :before, :after, and :around method Reflective facilities allow a program to reflect upon certain types modify particular primary methods. Class-wide aspects of itself. For example, in Lisp, eval permits before, after and around methods for arbitrary messages reflecting upon programs given as data, and catch and cannot be defmed without making alterations at the meta- throw allow reflecting upon the runtime stack. level.

Actor Languages Co&e’s ObjVLisp system [Cointe 19871permits a Me&lass hierarchy distinct from the class hierarchy. This An Actor [Agha] is a process that explicitly decides whether allows arbitrarily deep meta-regress,where appropriate. and how to handle or delegate any messagesit receives. This system allows the lookup method used by the This ability is used to construct futures, monitors, etc. system’s send primitive to be changed by manipulating the Actor languages are designed for multiprocessors; the . Metaclass customization can also be used to requirement that each actor be a separateprocess makes control internal object representations, method caching, and actors inefficient on single processors. Further, using a accessto instance variables. parallel programming language for sequential programming causesa certain mental overhead. Reflecting on the Smalltalk Virtual Smalltalk- [Goldberg 19761was similar in some respects Machine to the Actor languages. In Smalltalk-72, an object’s class was a process that repeatedly examined the object’s message Most of the existing object-oriented systems that permit and then dispatched on the message. As the meta-level system manipulation, such as 34X3, CLOS, language evolved, messagelookup was subsumed into the ObjVLisp, and ABCL/R Watanabe 19881have been Smalltalk Virtual Machine for efficiency’s sake and because constructed using Lisp-based metacimular interpreters. deviations from case-style method dispatching were rare and Reflection is then implemented by modifying the usualIy hard to understand. Smalltalk- permitted more language’s interpreter. Smalhalk-80, on the other hand, reflection than Smalltalk- because objects could uses a virtual machine. manipulate the messagestream. Although the Smalltalk-80 virtual machine is a code Replacing user-defmedmessage-handling with standardized interpreter that is usually implemented in machine language method lookup was a success. It led to efficient Smalltalk or C, the official definition of the virtual machine is written implementations and a large body of reusable software. in Smalltalk[Goldberg 831. Moreover, the SmaIltallc-80 However, the power of the Actor language is needed to deal debugger uses a byte-code interpreter written in Smalltalk. with parallelism and other aspectsof modem applications. Indeed, debugging and tracing are frequently cited as We believe that object-oriented systems should provide applications that are well addressedusing reflection. In primitive facilities that allow actor-like objects to be general, though, secondary interpeters are probably too constructed out of more rudimentary components. Thus, inefficient to serve as a practical mechanism for the the full power of actors will only be used when appropriate. implementation of reflective features. Hence, we have focused instead on adding certain reflective facilities to the Smalltalk virtual machine.

328 OOPSLA‘89 Proceedings October 1-6, 1989 exploited Smalltalk-80’s doesNotUnderstand: Smalltalk already exhibits many reflective facilities; mechanism to construct these objects, programs can examine their run-time stacks and can redefine their methods. These facilities were exploited by LaLonde When a messageis sent to a Smalltalk- object, the and Van Gulik mnde 19881to construct a backtracking method dictionaries associatedwith that object’s class and facility in Smalltalk. We can add more reflective facilities its superclassesare searchedat nmtime. If none of these by examining each part of Smalltalk and seeing how each classesimplement a method for a given message,the could be overridden. Smalltalk virtual machine sends the object the message doesNotUnderstand:. The original message selector 1) Variable read and write and messagearguments are bundled together in a Message object and passedas the argument to Variable accessescan be reflected upon in a number of doesNotUnderstand:. The default method for this ways. If variable accessesare implemented using messages, messageis stored in class Object, This method invokes the as in Selflungar 88] , then reflective mechanisms for Smalltalk &bugger, since sending an object a messageit messageswill also work for variables. Another alternative does not implement is usually a sign of programmer error. is to introduce active variables, as was done in Smalltalk- However, objects that override docsNotUnderstand: can by Messick and Beck [Messick 19851. This approach intercept unimplemented messageat runtime, and process involved modifying the Smalltalk- to convert them as they see fit. variable accessesinto messagesends to ActiveVariable objects, which in turn regulated accessto their contents. Encapsulators are ‘wrapped around” the objects they encapsulate. Unadorned Encapsulatorsforward every 2) Sending a message messagesent to them to their client object. However, pre- and post- actions (EPreAction and EPostAction) as Messagessent hy an object can be intercepted by modifying well as initialization code can be specified by overriding the SmalItalk-80 compiler to wrap code around each send certain default Encapsulator methods (EPreAction, operation. Mechanisms that allow a specialized interpreter EPostAction, and Elnitialize). EPreActions can to preempt the default one can also be used to intercept include messagescreening, synchronization, and the like. messagesends. The Smalltalk debugger is implemented EPostActions can gain access to the value returned, using an interpreter that runs on top of the Smalltalk perhaps altering the returned value, if appropriate. virtual machine. Intercepting each messagesent by an object seemsuseful primarily for applications like tracing Pascoe’sapproach, in effect, uses messageforwarding to an and debugging. encapsulatedcomponent to effect method lookup customization. This is messageforwarding, and not true 3) Receiving a message delegation, because the self problem [Liebermann 19861is not addressed(see below). We have concentrated on the mechanism for handling messagessent & an object. The messagesend is one of the Encapsulators are good for building objects like distributed fundamental notions upon which object-oriented systems objects [Bennett 19871 [McCullough 19871,since the are based, so redefining its meaning is very powerful. object being forwarded to is in another addressspace from Later, we will show how to efficiently redefine message the original object receiving the message. However, they look-up and some of its many uses. do not work well for atomic objects, since it is possible for the object being encapsulated to escapefrom the 4) Returns encapsulator and allow other objects to send it messages directly. If an object can intercept messagessent to it before dispatching them, its dispatching routine can inspect results Messick and Beck discuss a tool to insert code before and returned to it before returning them itself. Thus, redefining after a given method without having to recompile the returns falls out of redefining messagedispatching. method. They call such methods advised methods, after a related feature in Interlisp. They used this facility for setting conditional breakpoiits, for argument and result Changing Method-Lookup in type checking, for coercion, for tracing, and for changing Smalltalk method interfaces. Advised methods show the value of being able to wrap a piece of code around an existing Pascoe[pascoe 19861described a clever schemefor method without changing it. customizing method dispatch in Smalltalk-80. His approach, rather than relying on compiler and code One interesting aspect of Messick and Beck’s work is that it modifications, involved the creation of a parallel hierarchy illustrates how manipulation of the Smalltalk- system’s of classescalled Encapsulators. An Encapsulator is an self representation can be undertaken at several different object that surrounds another (single) object. Pascoe

October 1-6, 1989 OOPSLA ‘89 Proceedings 329 levels of the system. The implementation of active cache entry contains the class of the method stored in the variables took advantage of the fact that Smalltalk- cache, together with the address of the method itself. The allows the Smalltalk compiler itself to be modified by users linkedDispatch routine must determine whether the class of of the system. The advised method feature involved the the cached entry matches the class of the receiver of the manipulation of compiled methods. It is instructive to current messagesend. If this is the case (as it usually will contrast these approaches with those that use only pre- be) the method can be dispatched to directly. When there is existing reflective facilities (such as the backtracking work) a mismatch, the cache entry must be relinked by performing and with those that entail modification (or replacement) of a full method-lookup. Some implementations of in-line the virtual machine itself (see below). caching call the method itself directly, instead of using a dispatching routine. The code to check the validity of the Method Lookup in TS cache entry must then be prefixed to every compiled method. Customized method-lookup routines can be efficiently implemented. One technique was used by Chris Lanier as Deutsch and Schiffman note that this sort of dynamic code part of TS, an optimizing compiler for Smalltalk that we modification is generally condemned in modem are building [Johnson 198881 This technique employs a programming practice. It is, however, very much in the class instance variable that refers to a method lookup spirit of the work on reflection. routine for that class. It uses a variation of in-line caching, as originally implemented in PS, ParcPlace Smalltalk Under TS, each class stores its method look-up routine in [Deutsch 19831that allows custom method lookup routines one of its instance variables. Since the linkedDispatch and to be executed with almost no performance penalty. unlinkedDispatch routines are the method-lookup routines, redefining method lookup means creating new dispatch Note that the vast majority of classes will not need to routines. There is a new version of the linkedDispatch override method lookup. A mechanism for allowing routine for each redefinition of method lookup. The code method-lookup to be overridden should impose no overhead that links cache entries must check whether the dispatch on classes that do not use it. routine has changed, too, and might need to jump to a new dispatch routine. Classes that use the default method In-line method caching is a technique for optimizing lookup routine will behave exactly like PS, so method- method lookup that takes advantage of the dynamic locality lookup will continue to be fast. The overhead associated of type usage by caching the method last associated with a with this method lookup scheme was about the same as given messagesend m-line. Deutsch and Schiffman report that of method caching alone in PS. We plan to eventually that this strategy is effective about 95% of the time. write method-lookup routines in Typed Smalltalk, but at the moment all of them are written in machine language. In-line caching works as follows. A messagesend with no cache entry is anunlinked entry. For example, consider Reflective Facilities in Smalltalk this messagesend: Under ParcPlace Smalltalk (PS) we implemented our push receiver Stack the receiver.. . specialized method lookup routines in Smalltalk- itself. push argl,...,argn Stack the args... Whenever an object belonging to a class designated as a call unlinkedDispach ;Lookup and fill in cache dispatching class (using a in the class object’s header) is Selector to send... sent a message,that object is instead sent ;Untinked entries don’t use. dispatchMessage: aMessage. This feature is ;Send will return here... implemented using essentially the same mechanism as doesNotUnderstand:. The method associated with When the unlinkedDispatch routine is called it performs a dispatchMessage is then free to handle the message as it standard method-lookup, and associatesa method with the seesfit. A mechanism for allowing a dispatching class’s given receiver and selector. It then modifies the call in methods to call other class methods without reinvoking the place as follows before completing the send: dispatching mechanism is provided.

push receiver Stack the receiver... A related class type is the parentless class. These classes push argl,...,argn Stack the args. . . invoke the messagedispatching mechanism if the message call IinkedDispach ;Try prewicus method first. .. sent to them is not found in the method dictionary of the ;C/ass of cached method.. . first class searched. The effect achieved is the sameas that ;Method to callfirst... of removing the class’s superclass chain. Send will return here... These features are augmented with mechanisms for The modified call is said to be linked. (The changes made supporting lightweight anonymous classesand m&objects. to create the cache entry are shown in italics.) A linked Metaobjects are class objects that refer to a single instance,

330 OOPSLA‘89 Proceedings October 1-6, 1989 their referent. They are similar in this respect to and releasing it afterwards. Our implementations of Smalltalk’s Metaclass objects, which describe a single class monitors and atomic objects bear a fairly strong object. We currently implement lightweight classesand resemblance to those given in Pascoe 19861. metaobjects as subclassesof Behavior. We allow these objects to be introducted and removed from the inheritance A future object differs from an atomic object becausethe paths of individual objects dynamically. These class final methods that are executed belong to the value of the objects are not ma& visible to the parts of the Smalltalk future, not the future object itself. The future has a system that are involved with the management of the semaphoreand a value. The semaphore is originally system’s class hierarchy, and have no global names. The locked. Once released, the semaphoreis never locked again, figure below illustrates how a metaobject that specializes a and messagesare relayed to the new value of the future single instance of class Point fits into the class hierarchy. instead of being executed by the future itself.

The Smalltalk- code that follows illustrates a simple implementation for Future objects. The code below shows how a future object for the result of a block that calculates 2+2 might be created. The given block is executed in parallel with the active process. The promising: method immediately returns a Future object, which can be thought of as a place holder for the result being computed in parallel. Messages sent to the future (such as the printstring messagebelow) while the process computing the Future’s result is still in progress cause the current process to be suspended until the Future arrives.

f C- Future promising: (2+2]. f printstring ‘4.0’ Future class methodsfor: ‘instance creation’

The instance creation messagebelow creates an instance of Future promising the result of the given block. Classes that implement a dispatchMessage: method (other than the default one for class Object) use a bit in the class object’s header to indicate that this method should be Figure 1 executed any time a messageis sent to an instance of that class. We allow dispatching classesto execute The use of a doesNotUnderstand-based dispatching perform:withArguments: without reinvoking the mechanism limits the efficiency of the code that uses it. dispatchMessage: method. This is how the default Our TS based implementation of specialized method lookup dispatchMessage: method dispatches messages. routines based on in-line caching can be very efficient. The only overhead is the extra time needed to link dispatch promlslng: aBlock routines, which is very small. We believe that a synthesis 1aFuture 1 of the two approachesdiscussed above can retain the aFuture <- self new. flexibility associatedwith programming reflective code in *aFuture promising: aBlock Smalltalk-80, as well as the efficiency of the TS-based lookup customization scheme. The Future instance method below first allocates a semaphore. It then creates and starts a process that Applications calculates a result for the given block and signals this semaphore when this calculation is complete. The Future A classic example of the need for redefining message object itself is the immediate result of this method. dispatching is making an object that only responds to one messageat a time, i.e. an atomic object [Yokote 19861. An atomic object has a semaphore,and every process that sends a messageto it must first acquire that semaphore. When the messagereturns, the semaphoreis released. This is easily implemented by having the messagedispatch routine acquire the semaphorebefore executing the method

October 1-6, 1989 OOPSLA ‘89 Proceedings 331 Remote objects are like future objects in that they do not Future methodsfor: needto perform method look-up, but transform the message ‘initlallzation/dlspatchlng’ into another form. In the caseof remote objects, messages get translatedinto network packetsand sentto the machine promising: aBlock at which the objects are located. Bennett 19871 “Create a semaphore, and fork a block that [McCullough 1987-J. will it. The result of this block is stored in result... *’ Actors can also be implementedeasily. Each actor has a messagequeue and a process. The processrepeatedly reads a semaphore <- Semaphore new. messagefrom the messagequeue and then dispatcheson it. [result c- aBlock value. The messagedispatch routine for the actor simply turns the semaphore signal] fork. messageinto an object and places it onto the queue. %ell Languagesbased on delegationand prototypeslet each The dispatchMessage: method is invoked when the object have its own specializedmethods. We implement Future object is sent (nearly) any messagewhatsoever. In per-objectbehavior modification using Metaobjects. True the examplegiven above, the messagesent it is delegationLieberman 19861requires that the original self printstring. This method first tests to see whether the be maintainedsomehow when a messageis delegatedto one messagesent the Future is a promising: message. If so, of an object’scomponents. Efficiently rebinding self in it is dispatchedusing the inherited messagedispatching this fashion at runtime would seemto require modifications method.. Otherwise, the method waits until the Future to the Smalltalk virtual machine. arrives. It then tests the result to see if it is a SmallInteger. Since thesedo not have unique object pointers, they do not We haveinvestigated two strategiesthat can be employedat work with the become: message. In such cases,the value the Smalltalk level to implement this behavior. One is converted to a floating point value. Finally, the approachinvolves passing the “outer self” to an object’s become: messageis executedto exchangethe identities of componentas part of a messagedelegating the original the Future and result objects. messageto that component. Another approachentails augmentingan object’s componentswith a Component The beauty of using become: here is that all subsequent metaobject. This metaobjectscreens all its messagesfor referencesto the object pointer originally returned when the messagessent to self from itself, and forwards theseto the Future object was createdwill now refer directly to the object designatedas the component’scontainer. result object. Subsequentreferences to this object will no longer incur any dispatchingoverhead. In systemswhere There is a very strong similarity between the notions of become: is slow and dispatching is fast (e.g. TS) it would delegationto an object’scomponents and inhertance [Stein be better to omit the become:. The final act of the 19871.We contend [Johnson1988a] that inheritance,and method below (and henceof the Future object itself) is to multiple inheritancein particular, are overusedin forward the messagethat invoked dispatchMessage: (the situationswhere forwarding or delegatingmessages to printString) to the result object. componentswould be more appropriate. One reasonfor this might be that inheritance is frequently the best dispatchMessage: aMessage supportedcode sharing mechanismavailable. In contrast, messageforwarding must be implementedexplicitly on a “If rhis is our init message, /et it by... ” method-by-methodbasis. aMessage selector == #promising: ifTrue: [“super dispatchMessage: Dispatching classeslet the Smalltalk programmer aMessage]. experimentwith a number of alternateapproaches to the problem of composing new objects from existing ones. “Wait until our result is available...” Among theseare: semaphore wait. “If our result is a Smalllnteger, it has no oop.. ” (result isKindOf: Smalllnteger) ifTrue: [result + result asfloat]. “Become the result and do the deferred message.. . ’ result become: self. “super dispatchMessage: aMessage

332 OOPSLA‘89 Proceedings October 1-6, 1989 1) Priorttized forwarding to components of programming problems that are awkward to addressin conventional object-oriented systems. In Smalltalk-80, the It is easy, using dispatching classes, to construct objects addition of facilities for overriding the messagedispatch that test their instance (component) variables in some process on a class wide basis can provide much of the same prioritized order to see whether their contents responds to a power. given message,and to forward such messagesto these components. An object, during the course of its lifetime, may enter into a number of different relationships with other objects in its 2) Dynamic fields environment. Some of these relationships will be permanent, or at least relatively static, and others might be Message interception (sometimes in conjunction with quite ephemeral. Some of these relationships might be metaobjects) can also be used to construct objects with quite complex. In conventional object-oriented systems, dynamic fields. Such objects can respond to the standard one such relationship, inheritance, is well supported. external instance variable accessprotocol, and convert However, the facilities for allowing the programmer to referencesthey don’t understand to dictionary accesses. construct similarly powerful mechanisms of this sort of his Alternately, they can permit dictionary-style iteration over or her own are limited. It remains to be demonstrated that static, record-like objects. One scheme for doing this using such facilities will lead to the discovery of mechanisms of doesNotUnderstand: is given in [Foote 19881. enduring value. The reflective facilities discussedherein can allow such issues to be explored in Smalltalk-80. 3) Dynamic protection Adding a carefully chosen of reflective facilities to a Specialized dispatching routines could also perform dynamic language like Smalltalk- lets it solve many of the same protection functions, based on the class of the sender of the problems that a fully reflective system can, with much message. A protected object’s class (or metaobject) might greater efficiency. These facilities can be implemented so contain several dictionaries mapping classesor even that they have little impact on code that doesn’t use them. individual instances to sets of messageselectors. An object’s membership (or lack thereof) in one of these sets Smalltalk- is not well suited for parallel programming or would determine its elegibility to send the object the given distributed programming, as can be seen by the number of message. Some sort of wildcard conventions, as well as attempts to extend it for these areas. However, instead of default groups, might be allowed. extending the language repeatedly each time a wetiess is discovered, it is better to give it enough power to extend 4) Multiple views itself. This makes it more likely that an existing system can be modified to reuse it in future contexts that cannot An alternate way to protect objects is to export references now be predicted. By adding the ability to redefine message not to the objects themselves, but to objects that forward dispatching, object-oriented languages like Smalltalk- restricted sets of the original object’s protocol to the will have less need to be extended in the future. Reflective original objects. Such a scheme could permit different facilities can also assist complex systems in adapting to clients to have different “views” of an object. This changing requirements as they evolve by permitting a wider mechanism might resemble capabilities. range of mechanisms for fitting existing objects to new situations. 5) Protocol matching Acknowledgements Yet another application is the construction of protocol mapping adapters. These are objects that can be fitted The second author was supported by NSF contract CCR- between sets of existing objects to translate between 8715752. We would like to thank Peter Deutsch and differing sets of protocol assumptions. Such capabilities ParcPlace Systems for providing tools and support for the might prove valuable in constructing open systems [Hewitt PS based portion of this work. We are grateful to Brian 19831. Marick for helpful comments on an earlier draft of this Customized method dispatching code can also be be used for Paper. the collection of performance data, and dynamic optimizations such as result caching and coercion. Another References application is the construction of persistent objects. [Agha 19861 Gut Agha Conclusions ACTORS: A Model of Concurrent Computation in Distributed Systems Computational reflection provides a framework for MIT Press. 1986 organizing object-oriented systems that addressesa number

October l-6, 1989 OOPSLA ‘89 Proceedings 333 [Bennett 19871 [Hewitt 19831 John K. Bennett Carl Hewitt and Peter de Jong The Design and implementation of Analyzing the Role of Description and Actions Distributed Smalltalk in Open Systems OOPSLA ‘87 Proceedings AAAI ‘83, pages 162-I 67 Orlando, FL, October 4-8 1977 pages 118-330 [ lngalls 19781 [Bobrow 1988a] Daniel H. H. lngalls D. G. Bobrow, L. G. DeMichiel, R. P. Gabriel, The Smalltalk- Programming System S. E. Keene, G. Kiczales, and D. A. Moon Design and Implementation Common Lisp Object System Specification X3Jl3 5th ACM Symposium on POPL, pp. 9-15 Document 88-002R Tucson, AZ, USA, January 1978 SIGPIAN Notices, Volume 23, Special Issue, September 1988 [Johnson 1988a] Ralph E. Johnson and Brian Foote [Bobrow 1988b] Designing Reusable Classes Daniel 0. Bobrow and Gregor K&ales Journal of Object-Oriented Programming The Common Lisp Object System Volume I, Number 2, June/July 1988 Metaobject Kernel -- A Status Report pages 22-35 Proceedings of the 1988 Conference on Lisp and Functional Programming [Johnson 1988b] Ralph E. Johnson, Justin 0. Graver, and [Deutsch 19841 Laurance W. Zurawski L. Peter Deutsch and Allan M. Schiffman TS: An Optimizing Compiler for Smalltalk Efficient Implementation of the OOPSLA ‘88 Proceedings Smalltalk- System San Diego, CA, September 25-30, 1988 Proceedings of the Tenth Annual ACM Symposium pages 18-26 on Principles of Programming Languages, 1983, pages 297-302 [Keene 19891 Sonya E. Keene [Foote 19881 Object-Oriented Programming in Common Lisp Brian Foote A Programmer’s Introduction to CLOS Designing to Facilitate Change with Addison-Wesley, 1989 Object-Oriented Frameworks Masters Thesis, 1988 [LaLonde 19861 University of Illinois at Urbana-Champaign Wilf R. LaLonde, Dave A. Thomas and John R. Pugh An Exemplar Based Smalltalk [Goldberg 19761 OOPSLA ‘86 Proceedings Adele Goldberg and Alan Kay, editors Portland, OR, October 4-8 1977 pages 322-330 with the Learning Research Group Smalltalk- Instruction Manual [LaLonde 19881 Xerox Palo Alto Research Center Wilf R. LaLonde and Mark Van Gulik Building a Backtracking Facility in Smalltalk Without [Goldberg 19831 Kernel Support Adele Goldberg and David Robson OOPSLA ‘88 Proceedings Smalltalk-80: The Language and San Diego, CA, September 25-30, 1988 its Implementation pages 105-I 22 Addison-Wesley, Reading, MA, 1983 [Lieberman 19861 [Goldberg 19841 Henry Lieberman Adele Goldberg Using Protypical Objects to implement Smalltalk-80: The Interactive Shared Behavior Programming Environment in Object-Oriented Systems Addison-Wesley, Reading, MA, 1984 OOPSLA ‘86 Proceedings Portland, OR, October 4-8 1977 pages 214-223 [Halstead 19851 R. Halstead [Maes 1987a] MultiLISP: A language for Concurrent Pattie Maes Symbolic Computation Computational Reflection ACM Transactions on Programming Languages Artificial Intelligence Laboratory and Systems Vrije Universiteit Brussel October 1985, pages 501-538 Technical Report 87-2

334 OOPSLA ‘89 Proceedings October l-6, 1989 [Maes 1987b] [Tiemann 19881 Pattie Maes Michael D. Tiemann Concepts and Experiments in Solving the RPC problem in GNU C++ Computational Reflection 1988 USENIX C++ Conference OOPSLA ‘87 Proceedings Denver, CO, October 17-21 1988 Orlando, FL, October 4-8 1977 pages 147-155 [Ungar 19871 [McCullough 19871 David Ungar and Randall B. Smith Paul L. McCullough Seff: The Power of Simplicity Transparent Forwarding: First Steps OOPSLA ‘87 Proceedings OOPSLA ‘87 Proceedings Orlando, FL, October 4-8 1977 pages 227-242 Orlando, FL, October 4-8 1977 pages 331-341 [Yokote 19861 [Messick 19851 Yasuhiko Yokote and Mario Tokoro Steven L. Messick and Kent L. Beck The Design and Implementation of Active Variables in Smalltalk- ConcurrentSmalltalk Technical Report CR-85-09 OGPSLA ‘86 Proceedings Computer Research Lab, Tektronix, Inc., 1985 Portland, OR, September 29-October 2 1986, pages 331-340 [Pascoe 19861 Geoffrey A. Pascoe [Watanabe 19881 Encapsulators: A New Software Takuo Watanabe and Akinori Yonezawa Paradigm in Smalltalk- Reflection in an Object-Oriented Concurrent OOPSLA ‘86 Proceedings Language Portland, OR, September 29-October 2 1986, OOPSLA ‘88 Proceedings pages 341-346 San Diego, CA, September 25-30, 1988 pages 306-315 [Smith 19831 Brian Cantwell Smith Reflection and Semantics in Lisp Proceedings of the 1984 ACM Principles of Programming Languages Conference pages 23-35

[Smith 19871 Randall 8. Smith Experiences with the Alternate Reality Kit: An Example of the Tension Between Liieralism and Magic. CHI+GI 1987 Conference Proceedings

[Stefik 1986a] Mark Stefik and Daniel G. Bobrow Object-Oriented Programming: Themes and Variations Al Magazine 6(4): 40-62, Winter, 1986

[Stef ik 1986bJ M. Stefik, D. Bobrow and K. Kahn Integrating Access-Oriented Programming into a Multiprogramming Environment IEEE Software, 3, 1 (January 1986) 1O-18

[Stein 19871 Lynn Andes Stein Delegation is lnhertance OOPSLA ‘87 Proceedings Orlando, FL, October 4-8 1977 pages 138-l 46

[Stroustrup 19861 Bjarne Stroustrup The C++ Programming Language Addison-Wesley, Reading, MA, 1986

October l-6, 1969 OOPSLA ‘69 Proceedings 335